internal static void SerializeObject(Object obj, WriteOnlyDatagram datagram, SerializerState state) { if (obj == null) { datagram.WriteUInt((uint)SerializedTypeCode.Null, 8); } else if (obj is String) { datagram.WriteUInt((uint)SerializedTypeCode.String, 8); datagram.WriteString(obj as String); } else if (obj is MISP.ScriptList) { datagram.WriteUInt((uint)SerializedTypeCode.List, 8); var filteredList = new MISP.ScriptList( (obj as MISP.ScriptList).Where((o) => IsSerializableType(o))); datagram.WriteUInt((uint)filteredList.Count, 16); foreach (var item in filteredList) SerializeObject(item, datagram, state); } else if (obj is int) { datagram.WriteUInt((uint)SerializedTypeCode.Integer, 8); datagram.WriteUInt((uint)(obj as int?).Value, 32); } else if (obj is MISP.GenericScriptObject) { state.WriteObject(obj as MISP.GenericScriptObject, datagram); } }
private static MISP.ScriptList DecodeList(ReadOnlyDatagram datagram) { var r = new MISP.ScriptList(); uint count = 0; datagram.ReadUInt(out count, 8); byte[] temp = new byte[4]; for (int i = 0; i < count; ++i) { uint typeCode = 0; datagram.ReadUInt(out typeCode, 8); switch ((ScriptTypes)typeCode) { case ScriptTypes.List: r.Add(DecodeList(datagram)); break; case ScriptTypes.String: { String s; datagram.ReadString(out s); r.Add(s); } break; case ScriptTypes.Int32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToInt32(temp, 0)); break; case ScriptTypes.UInt32: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToUInt32(temp, 0)); break; case ScriptTypes.Single: datagram.ReadBytes(temp, 4); r.Add(BitConverter.ToSingle(temp, 0)); break; case ScriptTypes.Bool: { uint b = 0; datagram.ReadUInt(out b, 8); if (b == 0) r.Add(null); else r.Add(true); } break; default: throw new MISP.ScriptError("Error decoding message", null); } } return r; }
internal static Object DeserializeObject(ReadOnlyDatagram datagram, SerializerState state, Database database) { uint rawTypeCode = 0; if (!datagram.ReadUInt(out rawTypeCode, 8)) throw new DeserializeError(); switch ((SerializedTypeCode)rawTypeCode) { case SerializedTypeCode.Null: return null; case SerializedTypeCode.Integer: { uint value = 0; if (!datagram.ReadUInt(out value, 32)) throw new DeserializeError(); return (int)value; } case SerializedTypeCode.String: { String value = ""; if (!datagram.ReadString(out value)) throw new DeserializeError(); return value; } case SerializedTypeCode.List: { uint length = 0; if (!datagram.ReadUInt(out length, 16)) throw new DeserializeError(); var result = new MISP.ScriptList(); for (int i = 0; i < length; ++i) result.Add(DeserializeObject(datagram, state, database)); return result; } case SerializedTypeCode.InternalObject: return state.ReadObject(datagram, SerializedTypeCode.InternalObject, database); case SerializedTypeCode.NamedObject: return state.ReadObject(datagram, SerializedTypeCode.NamedObject, database); default: throw new DeserializeError(); } }
void IModule.BeginSimulation(Simulation sim) { this.sim = sim; sim.sendMessageHandler += (bytes) => { pendingMessages.Add(bytes); }; try { netSession = new Network.ServerSession(port, sim.debug); netSession.onClientJoined += (client) => { var welcomeDatagram = new Network.WriteOnlyDatagram(); welcomeDatagram.WriteUInt(0, 8); welcomeDatagram.WriteString(sim.Content.Module.Name); welcomeDatagram.WriteUInt((uint)sim.Content.Module.Version, 32); netSession.sendCriticalDatagram(client, welcomeDatagram.BufferAsArray, () => { sim.EnqueueEvent("on-new-client", new MISP.ScriptList(client)); }); }; netSession.onDatagramReceived += (client, bytes) => { var gram = new Network.ReadOnlyDatagram(bytes); while (gram.More) { uint messageCode = 0; gram.ReadUInt(out messageCode, 8); switch (messageCode) { case 0: //Should never receive this message. break; case 1: //Should never receive this message. break; case 2: { UInt32 length; gram.ReadUInt(out length, 32); byte[] message = new byte[length]; gram.ReadBytes(message, length); string messageID = null; MISP.ScriptList messageData = null; ScriptMessage.DecodeMessage(message, out messageID, out messageData); sim.EnqueueEvent(messageID, messageData); } break; } } }; } catch (Exception e) { System.Console.WriteLine("While trying to create a server module, " + e.Message); throw e; } }
public ClientModule(System.Net.IPAddress host, int port, ClientGame parentGame) { netSession = new Network.ClientSession(0, new System.Net.IPEndPoint(host, port), parentGame.Main.ScriptConsole.Write); netSession.onDatagramReceived += (data) => { var gram = new Network.ReadOnlyDatagram(data); while (gram.More) { uint messageCode = 0; gram.ReadUInt(out messageCode, 8); switch (messageCode) { case 0: if (simulation != null) { throw new InvalidProgramException(); } { String episodeName; uint version; gram.ReadString(out episodeName); gram.ReadUInt(out version, 32); parentGame.StartSimulation(episodeName, version); } break; case 1: { UInt32 entityID; UInt32 syncID; UInt32 dataLength; gram.ReadUInt(out entityID, 32); gram.ReadUInt(out syncID, 8); gram.ReadUInt(out dataLength, 32); var bytes = new byte[dataLength]; gram.ReadBytes(bytes, dataLength); if (syncables.ContainsKey(entityID)) { foreach (var syncable in syncables[entityID]) { //if (syncable.SyncID == syncID) syncable.ReadFullSync(new ReadOnlyDatagram(bytes)); } } } break; case 2: { UInt32 length; gram.ReadUInt(out length, 32); byte[] message = new byte[length]; gram.ReadBytes(message, length); string messageID = null; MISP.ScriptList messageData = null; ScriptMessage.DecodeMessage(message, out messageID, out messageData); simulation.EnqueueEvent(messageID, messageData); } break; } } }; parentGame.Main.Write("Connected to server " + host + " on port " + port + "\n"); }
private void SetupScript() { scriptEngine.AddGlobalVariable("clients", (s) => { return new MISP.ScriptList(ConnectedClients); }); scriptEngine.AddFunction("load", "name: Load an object from the database.", (context, arguments) => { var objectName = MISP.ScriptObject.AsString(arguments[0]); try { return database.LoadObject(objectName); } catch (Exception e) { //SendMessage(thisObject, "Failed to load object " + objectName + ": " + e.Message, true); return null; } }, "string name"); scriptEngine.AddFunction("reload", "name: Reloads an object from the database.", (context, arguments) => { var objectName = MISP.ScriptObject.AsString(arguments[0]); try { return database.ReLoadObject(objectName); } catch (Exception e) { //SendMessage(thisObject, "Failed to load object " + objectName + ": " + e.Message, true); return null; } }, "string name"); scriptEngine.AddFunction("create", "name: Create a new named object in the database.", (context, arguments) => { var objectName = MISP.ScriptObject.AsString(arguments[0]); try { return database.CreateObject(objectName); } catch (Exception e) { return null; } }, "string name"); scriptEngine.AddFunction("create-uniquely-named", "base-path: Directory to create new object in.", (context, arguments) => { var basePath = MISP.ScriptObject.AsString(arguments[0]); try { return database.CreateUniquelyNamedObject(basePath); } catch (Exception e) { return null; } }, "string base-path"); scriptEngine.AddFunction("save", "name: Save a named object.", (context, arguments) => { var objectName = MISP.ScriptObject.AsString(arguments[0]); try { database.SerializeObject(objectName); } catch (Exception e) { } return null; }, "string name"); scriptEngine.AddFunction("enumerate-database", "List all the database objects in a certain path.", (context, arguments) => { return database.EnumerateDirectory(arguments[0] as String); }, "string path"); scriptEngine.AddFunction("echo", "player<s> message: Send text to players.", (context, arguments) => { MISP.ScriptList to = null; if (arguments[0] is MISP.ScriptList) to = arguments[0] as MISP.ScriptList; else { to = new MISP.ScriptList(); to.Add(arguments[0]); } foreach (var obj in to) { if (obj is Client) (obj as Client).Send(MISP.ScriptObject.AsString(arguments[1])); else if (obj is MISP.ScriptObject) SendMessage(obj as MISP.ScriptObject, MISP.ScriptObject.AsString(arguments[1]), false); } return null; }, "to", "message"); scriptEngine.AddFunction("command", "player command: Send a command as if it came from player.", (context, arguments) => { Client client = null; foreach (var c in ConnectedClients) if (c.player == arguments[0]) client = c; if (client == null) client = new Client { player = arguments[0] as MISP.ScriptObject }; EnqueuAction(new Command( client, MISP.ScriptObject.AsString(arguments[1]))); return null; }, "object player", "string command"); scriptEngine.AddFunction("invoke", "seconds function arguments: Invoke a function in N seconds.", (context, arguments) => { var seconds = arguments[0] as int?; if (seconds == null || !seconds.HasValue) seconds = 0; EnqueuAction(new InvokeFunctionAction( MISP.Engine.ArgumentType<MISP.Function>(arguments[1]), MISP.Engine.ArgumentType<MISP.ScriptList>(arguments[2]), seconds.Value)); return null; }, "integer seconds", "function function", "list arguments"); scriptEngine.AddFunction("disconnect", "player : Disconnect a player.", (context, arguments) => { EnqueuAction(new DisconnectAction(MISP.Engine.ArgumentType<MISP.ScriptObject>(arguments[0]))); return null; }, "object player"); }