예제 #1
0
 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);
 }
예제 #2
0
        // 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;
        }
예제 #3
0
 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);
 }
예제 #4
0
        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);
        }
예제 #5
0
 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());
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        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;
        }
예제 #8
0
        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();
            });
        }
예제 #9
0
        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);
            });
        }
예제 #10
0
        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"));
                }
            }
        }
예제 #11
0
        public void AddAction(RemoteAction ra)
        {
            MyAssert.Assert(!remotes.ContainsKey(ra.Id));

            remotes.Add(ra.Id, ra);
        }
예제 #12
0
        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);
                }
            });
        }