using CommonAI; using CommonAI.Zone.ZoneEditor; using CommonAIServer.Node; using CommonLang.Net; using CommonServer.Server; using CommonServer.SSocket.SuperSocket; using System; using CommonFroms.G2D; using CommonAIServer.Node.Interface; using CommonLang; using CommonLang.Log; using CommonLang.Protocol; using RoomService.Net.BsServer; using System.Threading; using CommonAIServer.Connector; using CommonAI.Zone; using System.IO; using CommonLang.IO; using CommonLang.Property; namespace GameEditorPluginServer.Server { public class ServerNode : IServerListener { protected readonly Logger log = LoggerFactory.GetLogger("ServerNode"); private readonly ServerFactory mServerFactory; private readonly EditorTemplates mDataRoot; private readonly ZoneNodeConfig mConfig; private readonly ZoneNode mNode; private readonly SocketAcceptor mServer; private readonly int mSceneID; private readonly ServerCodec mCodec; public ServerNode(EditorTemplates dataroot, ZoneNodeConfig cfg, int sceneID) { this.mDataRoot = dataroot; this.mConfig = cfg; this.mSceneID = sceneID; this.mCodec = new ServerCodec(dataroot.Templates); this.mServerFactory = new ServerFactory(); this.mServer = mServerFactory.CreateServer(mCodec) as SocketAcceptor; this.mNode = new ZoneNode(dataroot, cfg); this.mNode.OnZoneStart += MNode_OnZoneStart; this.mNode.OnZoneStop += MNode_OnZoneStop; } public void Start() { var data = mNode.DataRoot.LoadScene(mSceneID, true, false); this.mNode.Start(data, null, null); } public void Dispose() { mServer.Dispose(); mNode.Stop(); } //------------------------------------------------------------------------------------------------- public ZoneNodeConfig Config { get { return mConfig; } } public ZoneNode Node { get { return mNode; } } public SocketAcceptor Server { get { return mServer; } } public EditorTemplates DataRoot { get { return mDataRoot; } } public bool Running { get { return mNode.IsRunning; } } public ServerCodec Codec { get { return mCodec; } } //------------------------------------------------------------------------------------------------- #region ServerAndRoom private void InternalOpen() { try { Random random = new Random(); int port = random.Next(10000, 60000); this.mServer.Open("127.0.0.1", port, this); } catch (Exception err) { log.Error(err.Message, err); } } private void MNode_OnZoneStop(BaseZoneNode zone) { } private void MNode_OnZoneStart(BaseZoneNode zone) { new Thread(InternalOpen).Start(); } void IServerListener.OnInit(IServer server) { } void IServerListener.OnDestory() { } ISessionListener IServerListener.OnSessionConnected(ISession session) { return new SessionPlayer(session as Session, mNode); } #endregion //------------------------------------------------------------------------------------------------- } //------------------------------------------------------------------------------------------------- public class ServerCodec : BattleCodec { private InputStream mInputStream; private OutputStream mOutputStream; private MemoryStream mBinBufferIn; private MemoryStream mBinBufferOut; private HashMap mTypeBytes = new HashMap(); public ServerCodec(TemplateManager templates) : base(templates) { this.mInputStream = new InputStream(null, Factory); this.mOutputStream = new OutputStream(null, Factory); this.mBinBufferIn = new MemoryStream(1024); this.mBinBufferOut = new MemoryStream(1024); } public override bool doDecode(Stream input, out object message) { lock (mInputStream) { mInputStream.SetStream(input); int typeInt = mInputStream.GetS32(); Type type = Factory.GetType(typeInt); if (type == null) { log.Error("Unknow Protocol : >>>" + typeInt + "<<<"); message = null; return false; } else { IMessage nm = (IMessage)ReflectionUtil.CreateInstance(type); nm.ReadExternal(mInputStream); if (nm is BattleMessage) { ((BattleMessage)nm).EndRead(Templates); } message = nm; return true; } } } public override bool doEncode(Stream output, object message) { lock (mOutputStream) { Type type = message.GetType(); int typeInt = Factory.GetTypeID(type); if (typeInt == 0) { log.Error("Unknow Protocol : >>>" + typeInt + "<<< - " + message.GetType().FullName); return false; } long pos = output.Position; mOutputStream.SetStream(output); mOutputStream.PutS32(typeInt); IMessage nm = (IMessage)message; if (nm is BattleMessage) { ((BattleMessage)nm).BeforeWrite(Templates); } nm.WriteExternal(mOutputStream); long len = output.Position - pos; Record rec; if (mTypeBytes.TryGetValue(type, out rec)) { rec.Bytes += len; rec.Count++; mTypeBytes.Put(type, rec); } else { rec.Bytes = len; rec.Count = 1; mTypeBytes.Put(type, rec); } return true; } } public HashMap GetSentTypeBytes() { lock (mOutputStream) { return new HashMap(mTypeBytes); } } public struct Record { public long Bytes; public int Count; } } //------------------------------------------------------------------------------------------------- internal class SessionPlayer : IPlayer, ISessionListener { private static Logger log = LoggerFactory.GetLogger("SessionPlayer"); private readonly ZoneNode node; private readonly Session session; private readonly SynchronizedBattleCodec codec; private readonly HashMap mAttributes = new HashMap(); private Action mRecvHandler; private EnterRoomRequestC2B login_data; private string player_uuid; private string display_name; private int unit_template_id; private int force; public SessionPlayer(Session session, ZoneNode node) { this.node = node; this.session = session; this.codec = new SynchronizedBattleCodec(node.Templates); } //---------------------------------------------------------------------------- #region IPlayer public string PlayerUUID { get { return player_uuid; } } public string DisplayName { get { return display_name; } } public ZoneNode.PlayerClient BindingPlayer { get; set; } bool IPlayer.IsAttribute(string key) { return mAttributes.ContainsKey(key); } void IPlayer.SetAttribute(string key, object value) { mAttributes.Put(key, value); } object IPlayer.GetAttribute(string key) { return mAttributes.Get(key); } void IPlayer.Send(IMessage msg) { session.Send(msg); } void IPlayer.Listen(Action handler) { mRecvHandler = handler; } void IPlayer.OnConnected(ZoneNode.PlayerClient binding) { } void IPlayer.OnDisconnect(ZoneNode.PlayerClient binding) { mRecvHandler = null; } #endregion //---------------------------------------------------------------------------- #region ISessionListener void ISessionListener.OnConnected(ISession session) { } void ISessionListener.OnDisconnected(ISession session, bool force, string reason) { if (node != null) { node.PlayerLeave(this.BindingPlayer.Actor, (c) => { }, (e) => { }, true); } } void ISessionListener.OnError(ISession session, Exception err) { } void ISessionListener.OnSentMessage(ISession session, object message) { } void ISessionListener.OnReceivedMessage(ISession session, object message) { try { if (message is EnterRoomRequestC2B) { do_EnterRoomResponseB2C(message as EnterRoomRequestC2B); } else if (message is LeaveRoomRequestC2B) { do_LeaveRoomRequestC2B(message as LeaveRoomRequestC2B); } else if (mRecvHandler != null) { mRecvHandler(message); } } catch (Exception err) { log.Error(err.Message, err); } } #endregion private void do_EnterRoomResponseB2C(EnterRoomRequestC2B req) { this.login_data = req; this.player_uuid = req.PlayerUUID; this.display_name = req.TestToken.PlayerDisplayName; this.unit_template_id = req.TestToken.Data.UnitTemplateID; this.force = req.TestToken.Data.Force; var temp = node.Templates.getUnit(unit_template_id); node.PlayerEnter(this, temp, force, 0, 0, null,0, (c) => { }, (e)=> { }); } private void do_LeaveRoomRequestC2B(LeaveRoomRequestC2B req) { this.login_data = null; node.PlayerLeave(this.BindingPlayer.Actor, (c) => { }, (e) => { }, false); } } }