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); }); }
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); } }); }