using System; using CommonLang.IO; using System.IO; using CommonLang.Protocol; using CommonLang.Property; using CommonLang.Log; using CommonLang.Net; using CommonAI.Zone; namespace CommonAI { public class BattleCodec : INetPackageCodec { protected Logger log = LoggerFactory.GetLogger("BattleCodec"); private TemplateManager templates = null; private IExternalizableFactory codec = null; public BattleCodec(TemplateManager templates) { this.codec = TemplateManager.MessageCodec; this.templates = templates; } public TemplateManager Templates { get { return templates; } } public CommonLang.IO.IExternalizableFactory Factory { get { return codec; } } const int FIXED_HEADER_SIZE = 4; const int DEFAULT_BUFFER_SIZE = 1024; public virtual bool doDecode(Stream input, out object message) { InputStream reader = new InputStream(input, codec); int typeInt = reader.GetS32(); Type type = codec.GetType(typeInt); if (type == null) { log.Error("Unknow Protocol : >>>" + typeInt + "<<<"); message = null; return false; } else { IMessage nm = (IMessage)ReflectionUtil.CreateInstance(type); nm.ReadExternal(reader); if (nm is BattleMessage) { ((BattleMessage)nm).EndRead(templates); } message = nm; return true; } } public virtual bool doEncode(Stream output, object message) { IMessage nm = (IMessage)message; OutputStream os = new OutputStream(output, codec); int typeInt = codec.GetTypeID(message.GetType()); if (typeInt == 0) { log.Error("Unknow Protocol : >>>" + typeInt + "<<< - " + message.GetType().FullName); return false; } if (nm is BattleMessage) { ((BattleMessage)nm).BeforeWrite(templates); } os.PutS32(typeInt); nm.WriteExternal(os); return true; } } public class SynchronizedBattleCodec : BattleCodec { private InputStream mInputStream; private OutputStream mOutputStream; private MemoryStream mBinBufferIn; private MemoryStream mBinBufferOut; public SynchronizedBattleCodec(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); try { 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; } } catch (Exception e) { message = null; log.Error("[doDecodeBin] error::" + e.Message, e); return false; } finally { mInputStream.SetStream(null); } } } public override bool doEncode(Stream output, object message) { lock (mOutputStream) { mOutputStream.SetStream(output); try { IMessage nm = (IMessage)message; int typeInt = Factory.GetTypeID(message.GetType()); if (typeInt == 0) { log.Error("Unknow Protocol : >>>" + typeInt + "<<< - " + message.GetType().FullName); return false; } mOutputStream.PutS32(typeInt); if (nm is BattleMessage) { ((BattleMessage)nm).BeforeWrite(Templates); } nm.WriteExternal(mOutputStream); return true; } finally { mOutputStream.SetStream(null); } } } public bool doDecodeBin(byte[] input, out object message) { lock (mBinBufferIn) { mBinBufferIn.Position = 0; mBinBufferIn.Write(input, 0, input.Length); mBinBufferIn.Position = 0; return doDecode(mBinBufferIn, out message); } } public bool doEncodeBin(out byte[] output, object message) { lock (mBinBufferOut) { mBinBufferOut.Position = 0; if (doEncode(mBinBufferOut, message)) { output = new byte[mBinBufferOut.Position]; Array.Copy(mBinBufferOut.GetBuffer(), 0, output, 0, output.Length); return true; } output = null; return false; } } } }