void OnWorldValidateRequest(Node n, Guid actionId, WorldInitializer init) { all.AddWorldValidator(init); //Log.LogWriteLine("Validating for world {0}", info.worldPos); //myHost.SendMessage(serverHost, MessageType.ACCEPT, actionId); RemoteAction.Sucess(n, actionId); }
// questionable design choices for sake of smoother application public void Respond(ref RemoteAction ra, Action <Response, Stream> followUp_) { followUp = followUp_; MyAssert.Assert(ra == null); ra = this; }
void OnPlayerValidateRequest(Node n, Guid actionId, PlayerInfo info, PlayerData pd) { all.AddPlayerValidator(info, pd); //Log.LogWriteLine("Validating for {0}", info); //myHost.SendMessage(serverHost, MessageType.ACCEPT, actionId); RemoteAction.Sucess(n, actionId); }
static public RemoteAction Send(OverlayHost myHost, OverlayEndpoint remoteHost, Node.DisconnectProcessor dp, MessageType mt, params object[] args) { RemoteAction ra = new RemoteAction(); ra.remoteHost = remoteHost; bool assigned = false; for (int i = 0; i < args.Length; ++i) { if (args[i].GetType() == typeof(RemoteActionIdInject)) { args[i] = ra.Id; // id is injected at first RemoteActionIdInject argument assigned = true; break; } } if (!assigned) { List <object> lst = new List <object>(); lst.Add(ra.Id); // or in front if there isn't one lst.AddRange(args); args = lst.ToArray(); } if (dp != null) { myHost.TryConnectAsync(remoteHost, dp); } myHost.SendMessage(remoteHost, mt, args); return(ra); }
protected override void ProcessClientMessage(MessageType mt, Stream stm, Node n) { if (mt == MessageType.NEW_PLAYER_REQUEST) { Guid player = Serializer.Deserialize <Guid>(stm); OnNewPlayerRequest(player, n.info.remote); } else if (mt == MessageType.NEW_WORLD_REQUEST) { Point worldPos = Serializer.Deserialize <Point>(stm); OnNewWorldRequest(worldPos, null, 0); } else if (mt == MessageType.NEW_VALIDATOR) { OnNewValidator(n.info.remote.addr); } else if (mt == MessageType.RESPONSE) { RemoteAction.Process(remoteActions, n, stm); } else if (mt == MessageType.STOP_VALIDATING) { OnStopValidating(n); } else { throw new Exception("Client.ProcessClientMessage bad message type " + mt.ToString()); } }
static public void Process(RemoteActionRepository rar, Node n, Stream st) { Response r = Serializer.Deserialize <Response>(st); Guid id = Serializer.Deserialize <Guid>(st); RemoteAction ra = rar.Get(id); ra.FollowUp(n, st, r); rar.Remove(id); }
static public void Process(ref RemoteAction ra, Node n, Stream st) { Response r = Serializer.Deserialize <Response>(st); Guid id = Serializer.Deserialize <Guid>(st); MyAssert.Assert(ra.Id == id); ra.FollowUp(n, st, r); ra = null; }
void OnLock(Node n, Guid remoteActionId) { //Log.Dump(); if (locked != null) { Log.Dump(info, n.info.remote, "already locked"); RemoteAction.Fail(n, remoteActionId); return; } if (finalizing) { Log.Dump(info, n.info.remote, "cannot lock, finializing"); RemoteAction.Fail(n, remoteActionId); return; } RemoteAction .Send(Host, n.info.remote, null, MessageType.RESPONSE, Response.SUCCESS, remoteActionId, new RemoteActionIdInject(), playerData) .Respond(ref locked, (res, str) => { //Log.Dump("unlocking", res); if (res == Response.SUCCESS) { PlayerData modifiedData = Serializer.Deserialize <PlayerData>(str); if (playerData.ToString() == modifiedData.ToString()) { throw new Exception(Log.StDump(playerData, n.info, "unchanged")); } //Log.Dump(info.name, "from ", playerData); playerData = modifiedData; //Log.Dump(info.name, "to ", playerData); //Log.Dump(info, "unlocking got new data", pdu); MessageToAgent(MessageType.PLAYER_INFO_VAR, playerData); } //else // Log.Dump(info, "unlocking - unchanged"); ExecuteDelayedActions(); }); }
void NewPlayerProcess(IPEndPoint clientAddr, Guid id, int generation, PlayerData pd) { MyAssert.Assert(!playerLocks.Contains(id)); ManualLock <Guid> lck = new ManualLock <Guid>(playerLocks, id); if (!validatorPool.Any()) { throw new Exception("no validators!"); } string playerName = PlayerNameMap(playerCounter++); string fullName = "player " + playerName + (generation == 0 ? "" : " (" + generation + ")"); OverlayEndpoint validatorHost = new OverlayEndpoint(validatorPool.Random(n => r.Next(n)), new OverlayHostName("validator " + fullName)); OverlayEndpoint playerNewHost = new OverlayEndpoint(clientAddr, new OverlayHostName("agent " + fullName)); OverlayEndpoint playerClient = new OverlayEndpoint(clientAddr, Client.hostName); OverlayEndpoint validatorClient = new OverlayEndpoint(validatorHost.addr, Client.hostName); PlayerInfo playerInfo = new PlayerInfo(id, playerNewHost, validatorHost, playerName, generation); RemoteAction .Send(Host, validatorClient, ProcessClientDisconnect, MessageType.PLAYER_VALIDATOR_ASSIGN, playerInfo, pd) .Respond(remoteActions, lck, (res, stm) => { if (playerInfo.generation == 0) { MyAssert.Assert(!players.ContainsKey(playerInfo.id)); players.Add(playerInfo.id, playerInfo); } else { MyAssert.Assert(players.ContainsKey(playerInfo.id)); players[playerInfo.id] = playerInfo; } MessageClient(playerClient, MessageType.NEW_PLAYER_REQUEST_SUCCESS, playerInfo); Log.Console("New player " + playerInfo.name + " validated by " + playerInfo.validatorHost.addr); }); }
protected override void ProcessWorldMessage(MessageType mt, Stream stm, Node n, WorldInfo inf) { if (mt == MessageType.LOCK_VAR) { Guid remoteActionId = Serializer.Deserialize <Guid>(stm); OnLock(n, remoteActionId); } else if (mt == MessageType.UNLOCK_VAR) { RemoteAction.Process(ref locked, n, stm); if (finalizing) { MyAssert.Assert(locked == null); OnFinalizedVerifier(); } } else { if (finalizing) { Log.Dump(info, " finalizing - ignored message:", mt); return; } if (mt == MessageType.PICKUP_TELEPORT) { ProcessOrDelay(OnPickupTeleport); } else if (mt == MessageType.PICKUP_BLOCK) { ProcessOrDelay(OnPickupBlock); } else if (mt == MessageType.PLAYER_DISCONNECT) { ProcessOrDelay(OnDisconnect); } else { throw new Exception(Log.StDump(info, inf, mt, "unexpected message")); } } }
public void AddAction(RemoteAction ra) { MyAssert.Assert(!remotes.ContainsKey(ra.Id)); remotes.Add(ra.Id, ra); }
void OnNewWorldRequest(Point worldPos, WorldSerialized ser, int generation) { if (worlds.ContainsKey(worldPos)) { Log.Dump(worldPos, "world alrady present"); return; } if (!validatorPool.Any()) { throw new Exception("no validators!"); } ManualLock <Point> lck = new ManualLock <Point>(worldLocks, worldPos); if (!lck.Locked) { Log.Dump(worldPos, "can't work, locked"); return; } string hostName = "host world " + worldPos; if (generation != 0) { hostName = hostName + " (" + generation + ")"; } OverlayEndpoint validatorHost = new OverlayEndpoint(validatorPool.Random(n => r.Next(n)), new OverlayHostName(hostName)); WorldInitializer init; WorldInfo newWorld; bool hasSpawn = false; if (ser == null) { WorldSeed seed = new WorldSeed(r.Next(), RandomColor(worldPos)); if (serverSpawnDensity == 0) { if (worldPos == Point.Zero) { hasSpawn = true; } } else if ((worldPos.x % serverSpawnDensity == 0) && (worldPos.y % serverSpawnDensity == 0)) { hasSpawn = true; } newWorld = new WorldInfo(worldPos, validatorHost, generation, hasSpawn); init = new WorldInitializer(newWorld, seed); } else { hasSpawn = ser.spawnPos.HasValue; newWorld = new WorldInfo(worldPos, validatorHost, generation, hasSpawn); init = new WorldInitializer(newWorld, ser); } OverlayEndpoint validatorClient = new OverlayEndpoint(validatorHost.addr, Client.hostName); RemoteAction .Send(Host, validatorClient, ProcessClientDisconnect, MessageType.WORLD_VALIDATOR_ASSIGN, init) .Respond(remoteActions, lck, (res, stm) => { if (res != Response.SUCCESS) { throw new Exception(Log.StDump("unexpected", res)); } //if (hasSpawn == true) // spawnWorlds.Add(worldPos); worlds.Add(newWorld.position, newWorld); //Log.LogWriteLine("New world " + worldPos + " validated by " + validatorHost.addr); foreach (Point p in Point.SymmetricRange(Point.One)) { if (p == Point.Zero) { continue; } Point neighborPos = p + newWorld.position; if (!worlds.ContainsKey(neighborPos)) { continue; } WorldInfo neighborWorld = worlds[neighborPos]; MessageWorld(neighborWorld, MessageType.NEW_NEIGHBOR, newWorld); MessageWorld(newWorld, MessageType.NEW_NEIGHBOR, neighborWorld); } }); }