using CommonAI.Zone; using CommonAI.Zone.Instance; using CommonAI.Zone.ZoneEditor; using CommonAIClient.Client; using CommonAIServer.Connector; using CommonAIServer.Node; using CommonFroms; using CommonFroms.G2D; using CommonFroms.Utils; using CommonLang; using CommonLang.Vector; using GameEditorPlugin.Win32.BattleClient; using GameEditorPluginServer.Client; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Windows.Forms; namespace GameEditorPluginServer.Server { public partial class FormServer : Form { private ConsoleOutput console; private ServerNode server; private ClientLoader client_loader; private BattleView battle_view; private DirectoryInfo dataDir; public FormServer(DirectoryInfo dataDir, int sceneID, ZoneNodeConfig cfg = null) { InitializeComponent(); this.console = new ConsoleOutput(); this.pictureBoxRoomLayer.MouseWheel += new MouseEventHandler(pictureBoxRoomLayer_MouseWheel); this.Shown += FormServer_Shown; this.FormClosing += FormServer_FormClosing; this.FormClosed += FormServer_FormClosed; this.Disposed += FormServer_Disposed; this.dataDir = dataDir; var templates = new EditorTemplates(dataDir.FullName, TemplateManager.MessageCodec); templates.LoadAllTemplates(); FormLauncher.Templates = templates; if (cfg == null) { cfg = new ZoneNodeConfig(); cfg.GAME_UPDATE_INTERVAL_MS = 1000 / templates.Templates.CFG.SYSTEM_FPS; cfg.CLIENT_SYNC_OBJECT_IN_RANGE = (int)templates.Templates.CFG.CLIENT_UNIT_MOVE_MODIFY_MAX_RANGE; cfg.CLIENT_SYNC_OBJECT_OUT_RANGE = (int)(cfg.CLIENT_SYNC_OBJECT_OUT_RANGE * 1.25f); } this.server = new ServerNode(templates, cfg, sceneID); this.client_loader = new ClientLoader(server); this.server.Node.EnableAOI = chk_EnableAOI.Checked; this.server.Node.OnZoneStart += Node_OnZoneStart; this.server.Node.OnZoneStop += Node_OnZoneStop; this.server.Start(); } private void FormServer_Disposed(object sender, EventArgs e) { server.Dispose(); } private void FormServer_Shown(object sender, EventArgs e) { console.DockTo = this; console.Show(); } private void FormServer_FormClosed(object sender, FormClosedEventArgs e) { console.Close(); client_loader.DisposeClients(); } private void FormServer_FormClosing(object sender, FormClosingEventArgs e) { } private void Node_OnZoneStart(BaseZoneNode zone) { this.timer2.QueueTask(() => { this.battle_view = new BattleView(server); this.battle_view.Layer.LayerInit += Layer_LayerInit; }); } private void Node_OnZoneStop(BaseZoneNode zone) { this.timer2.QueueTask(() => { this.Close(); }); } private void Layer_LayerInit(CommonAI.ZoneClient.ZoneLayer layer) { var bv = battle_view; if (bv != null) { float scale = Math.Max( ((float)pictureBoxRoomLayer.Width) / bv.Width, ((float)pictureBoxRoomLayer.Height) / bv.Height); bv.setCamera(bv.Width / 2, bv.Height / 2); bv.setCameraScale(scale, scale); } this.client_loader.AddRandomClient(); } private void timer2_Tick(object sender, EventArgs e) { if (server.Running) { if (server != null) { this.Text = "FormServer : " + server.Server.ClientConnectString; } if (battle_view != null) { battle_view.IsSyncPos = chk_ServerVisible.Checked; } if (battle_view != null) { battle_view.update(); } if (chk_ServerVisible.Checked) { pictureBoxRoomLayer.Refresh(); } } } //---------------------------------------------------------------------------------------------------------------------- #region __BattleView__ internal class BattleLocalView : BattleLocal { private EditorScene mZone; public BattleLocalView(ServerNode server) : base(server.Node.DataRoot) { this.mZone = server.Node.Zone; this.Layer.ProcessMessage(new CommonAI.ZoneClient.ClientEnterScene(mZone.Data.ID, mZone.SpaceDivSize, server.Node.Zone.Templates.ResourceVersion)); } public override EditorScene Zone { get { return mZone; } } } internal class BattleView : DisplayBattleLocal<BattleLocalView> { public ZoneNode Node { get { return server.Node; } } public bool IsSyncPos { get; set; } private ServerNode server; private long mLastUpdateTime; public BattleView(ServerNode server) { base.ShowGuardRange = false; base.ShowAttackRange = false; base.ShowDamageRange = false; base.ShowName = true; base.ShowHP = true; base.ShowSpaceDiv = false; this.server = server; base.InitClient(new BattleLocalView(server)); this.server.Node.Zone.OnPostEvent += zone_OnPostEvent; this.server.Node.Zone.OnUpdate += zone_OnUpdate; } private void zone_OnPostEvent(InstanceZone zone, Event e) { Battle.onEventHandler(e); } private void zone_OnUpdate(CommonAI.Zone.Instance.InstanceZone zone) { if (IsSyncPos) { SyncPosEvent.UnitPos pos = new SyncPosEvent.UnitPos(); SyncPosEvent.UnitState st = new SyncPosEvent.UnitState(); foreach (CommonAI.Zone.Instance.InstanceZoneObject so in server.Node.Zone.AllObjects) { CommonAI.ZoneClient.ZoneObject co = Client.Layer.GetObject(so.ID); if (co != null) { pos = so.GetSyncPos(); co.SyncPos(ref pos); if (so is InstanceUnit) { st = (so as InstanceUnit).GetSyncState(); co.SyncPos(ref st); } } } } } protected override void clientUpdate(int intervalMS) { Battle.BeginUpdate(intervalMS); Battle.Update(); } public void update() { long curTime = CommonLang.CUtils.CurrentTimeMS; if (mLastUpdateTime == 0) { mLastUpdateTime = curTime; } int intervalMS = (int)(curTime - mLastUpdateTime); this.mLastUpdateTime = curTime; base.update(intervalMS); base.update_flush(); } } //---------------------------------------------------------------------------------------------------------------------- private Vector2 pic_lastMouesDown; private Vector2 pic_lastCameraPos; private void pictureBoxRoomLayer_MouseWheel(object sender, MouseEventArgs e) { try { BattleView bv = battle_view; if (bv != null) { int d = CMath.getDirect(e.Delta); if (d > 0) { float newD = bv.getCameraScale() * 1.1f; bv.setCameraScale(newD, newD); } else if (d < 0) { float newD = bv.getCameraScale() / 1.1f; bv.setCameraScale(newD, newD); } } } catch (Exception err) { Console.WriteLine(err.Message); } } private void pictureBoxRoomLayer_MouseDown(object sender, MouseEventArgs e) { pictureBoxRoomLayer.Focus(); BattleView bv = battle_view; if (bv != null) { if (e.Button == MouseButtons.Left) { bv.PickObject( bv.screenToWorldX(e.X), bv.screenToWorldY(e.Y)); } else if (e.Button == MouseButtons.Right) { pic_lastMouesDown = new Vector2(e.Location.X, e.Location.Y); pic_lastCameraPos = new Vector2(bv.CameraX, bv.CameraY); } } } private void pictureBoxRoomLayer_MouseUp(object sender, MouseEventArgs e) { pic_lastMouesDown = null; pic_lastCameraPos = null; } private void pictureBoxRoomLayer_MouseMove(object sender, MouseEventArgs e) { BattleView bv = battle_view; if (bv != null) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { if (pic_lastMouesDown != null) { float x = pic_lastCameraPos.X + bv.screenToWorldSizeX(pic_lastMouesDown.X - e.X); float y = pic_lastCameraPos.Y + bv.screenToWorldSizeY(pic_lastMouesDown.Y - e.Y); bv.setCamera(x, y); } } } } private void pictureBoxRoomLayer_Paint(object sender, PaintEventArgs e) { try { if (chk_ServerVisible.Checked) { BattleView bv = battle_view; if (bv != null) { bv.setWindow(new RectangleF(0, 0, pictureBoxRoomLayer.Width, pictureBoxRoomLayer.Height)); bv.render(e.Graphics); } } } catch (Exception err) { Console.WriteLine(err.Message); } } #endregion //---------------------------------------------------------------------------------------------------------------------- #region __测试客户端__ private class ClientLoader : TestClientLoader { private static int id_gen = 0; private readonly ServerNode server; private Random random = new Random(); private List<FormClient> client_list = new List<FormClient>(); public ClientLoader(ServerNode server) { this.server = server; } public override CommonAI.ZoneServer.CreateUnitInfoR2B GenUnitInfoR2B(int unitID) { CommonAI.ZoneServer.CreateUnitInfoR2B ret = new CommonAI.ZoneServer.CreateUnitInfoR2B(); ret.UnitTemplateID = unitID; return ret; } public override Type ZoneFactoryType { get { return TemplateManager.Factory.GetType(); } } public void DisposeClients() { foreach (var f in client_list) { f.Dispose(); } } public void AddRandomClient() { UnitInfo info; PlayerStartAbilityData start; var node = server.Node; if (node.Zone.TryGetTestTemplate(out info, out start, random)) { var enter = GenUnitInfoR2B(info.ID); enter.Force = start.START_Force; var client = new FormTestClient(); client.Init( server.Config, info.Name + "_" + id_gen++, // player_uuid node.SceneID.ToString(), server.Server.ClientConnectString, typeof(CommonNetwork.Sockets.NetSession).FullName, enter); client_list.Add(client); client.Show(); } } public void AddTestClient() { UnitInfo info; PlayerStartAbilityData start; var node = server.Node; if (node.Zone.TryGetTestTemplate(out info, out start, random)) { var enter = GenUnitInfoR2B(info.ID); enter.Force = start.START_Force; FormTestClient.StartLauncher( server.Config, info.Name + "_" + id_gen++, // player_uuid server.Server.ClientConnectString, node.SceneID, enter, this, (launcher) => { enter.UnitTemplateID = launcher.UnitTemplateID; enter.Force = launcher.Force; var client = new FormTestClient(); client.Init( server.Config, launcher.PlayerUUID, // player_uuid node.SceneID.ToString(), server.Server.ClientConnectString, launcher.NetDirver, enter); client_list.Add(client); client.Show(); launcher.Close(); return true; }).Show(); } } } #endregion private void btn_AddPlayer_Click(object sender, EventArgs e) { client_loader.AddTestClient(); } private void btn_EmulateDelay_Click(object sender, EventArgs e) { int min, max; server.Server.GetEmulateLaggingMS(out min, out max); string text = G2DTextDialog.Show(string.Format("{0} - {1}", min, max), "模拟网络延时"); try { var kv = text.Split(new char[] { '-' }, 2, StringSplitOptions.RemoveEmptyEntries); if (kv.Length == 2) { min = int.Parse(kv[0]); max = int.Parse(kv[1]); server.Server.SetEmulateLaggingMS(min, max); } else { min = int.Parse(text); server.Server.SetEmulateLaggingMS(min, min); } } catch (Exception err) { MessageBox.Show(err.Message); } } private void btn_Bots_Click(object sender, EventArgs e) { try { ProcessStartInfo start = new ProcessStartInfo( Application.StartupPath + @"\CommonAIServer.Connector.exe", string.Format("FactoryClass={0} DataRoot=\"{1}\" ConnectString={2}", TemplateManager.Factory.GetType().FullName, dataDir.FullName, server.Server.ClientConnectString )); start.WorkingDirectory = Application.StartupPath; Process.Start(start); } catch (Exception err) { MessageBox.Show(err.Message); } } private void btn_ShowMsgBytes_Click(object sender, EventArgs e) { var msg_bytes_rec = new FormMsgBytes(server.Codec); msg_bytes_rec.Show(); msg_bytes_rec.BringToFront(); } private void btn_GC_Click(object sender, EventArgs e) { System.GC.Collect(); } private void btn_disconnectAll_Click(object sender, EventArgs e) { foreach (var session in server.Server.GetSessions()) { session.Disconnect(true); } } private void chk_EnableAOI_Click(object sender, EventArgs e) { server.Node.EnableAOI = chk_EnableAOI.Checked; } } }