Exemplo n.º 1
0
        /// <summary>
        /// Handles the loss of a player
        /// </summary>
        public void lostPlayer(Player player)
        {
            if (player == null)
            {
                Log.write(TLog.Error, "lostPlayer(): Called with null player.");
                return;
            }

            using (LogAssume.Assume(_logger))
            {     //Is it present in our list?
                if (!_players.ContainsKey(player._id))
                { //Notify and discontinue
                    Log.write(TLog.Error, "Lost player '{0}' who wasn't present in the ZoneServer list.", player);
                    return;
                }

                //Lets update the players silence list
                if (player._client._ipe.Address != null)
                {
                    IPAddress addy = player._client._ipe.Address;
                    if ((_playerSilenced.ContainsKey(addy)) && _playerSilenced[addy].Keys.Count > 0)
                    {
                        int min = 0; DateTime time = DateTime.Now;
                        foreach (int length in _playerSilenced[addy].Keys)
                        {
                            min = length;
                        }
                        if (_playerSilenced[addy].Values.Count > 0)
                        {
                            foreach (DateTime timer in _playerSilenced[addy].Values)
                            {
                                time = timer;
                            }
                        }
                        _playerSilenced.Remove(addy);
                        _playerSilenced.Add(addy, new Dictionary <int, DateTime>());
                        _playerSilenced[addy].Add(min, time);
                    }
                }

                //He's gone!
                _players.Remove(player._id);
                Log.write(TLog.Normal, "Lost player: {0} ({1})", player, player._client._ipe);

                //Make sure his stats get updated
                if (!IsStandalone)
                {
                    if (player._bDBLoaded)
                    {
                        _db.updatePlayer(player);
                    }

                    //We've lost him!
                    _db.lostPlayer(player);
                }

                //Set a destroy timer. This prevents lingering clients from not fully disconnecting
                player._client._tickDestroy = Environment.TickCount;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Triggered when the client is ready to download the game state
        /// </summary>
        static public void Handle_CS_Ready(CS_Ready pkt, Player player)
        {
            using (LogAssume.Assume(player._server._logger))
            {                   //Fake patch server packet
                SC_PatchInfo pinfo = new SC_PatchInfo();

                pinfo.Unk1        = false;
                pinfo.patchServer = "patch.station.sony.com";
                pinfo.patchPort   = 0x1b58;
                pinfo.patchXml    = "patch/infantry/Zone7130.xml";

                player._client.sendReliable(pinfo);

                //Send him the asset list
                SC_AssetInfo assets = new SC_AssetInfo(Helpers._server._assets.getAssetList());

                //Optional updates?
                if ((int)player.PermissionLevel >= 3)
                {
                    assets.bOptionalUpdate = true;
                }
                else
                {
                    assets.bOptionalUpdate = false;
                }

                player._client.sendReliable(assets);

                //We can now consider him past the login process
                player._bLoggedIn = true;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Attempts to create and initialize a connection to the DB server
        /// </summary>
        public bool connect(IPEndPoint dbPoint, bool bBlock)
        {       //Assume the worst
            _syncStart.Reset();
            _bLoginSuccess = false;

            using (LogAssume.Assume(_logger))
            {
                Log.write("Connecting to database server ({0})..", dbPoint);

                //Start our connection
                _conn.begin(dbPoint);

                //Send our initial packet
                CS_Initial init = new CS_Initial();

                _conn._client._connectionID = init.connectionID = new Random().Next();
                init.CRCLength    = Client.crcLength;
                init.udpMaxPacket = Client.udpMaxSize;

                _conn._client.send(init);

                _syncStart.WaitOne(10000);

                //Reset our event
                _syncStart.Reset();

                _server._lastDBAttempt = Environment.TickCount;

                //Were we successful?
                return(_bLoginSuccess);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Begins all server processes, and starts accepting clients.
        /// </summary>
        public void begin()
        {               //Start up the network
            _logger      = Log.createClient("Zone");
            base._logger = Log.createClient("Network");

            IPEndPoint listenPoint = new IPEndPoint(
                IPAddress.Parse("0.0.0.0"), _bindPort);

            base.begin(listenPoint);

            _pingResponder.Begin(new IPEndPoint(IPAddress.Parse("0.0.0.0"), _bindPort + 1));

            //Start handling our arenas;
            using (LogAssume.Assume(_logger))
                handleArenas();
        }
Exemplo n.º 5
0
        /// <summary>
        /// Triggered when the client is attempting to enter the game and sends his security reply
        /// </summary>
        static public void Handle_CS_RequestUpdate(CS_RequestUpdate pkt, Player player)
        {               //If the player isn't logged in, ignore
            if (!player._bLoggedIn)
            {           //Log and abort
                Log.write(TLog.Warning, "Player {0} tried to send asset request while not logged in.", player);
                player.disconnect();
                return;
            }

            //Delegate it to another thread so we don't spend ages caching
            LogClient logger = Log.getCurrent();

            ThreadPool.QueueUserWorkItem(
                delegate(object state)
            {
                using (LogAssume.Assume(logger))
                {                               //Prepare a list of cached assets
                    List <SC_AssetUpdateInfo.AssetUpdate> cache = new List <SC_AssetUpdateInfo.AssetUpdate>();

                    foreach (CS_RequestUpdate.Update update in pkt.updates)
                    {                                   //Find the matching cached asset
                        AssetManager.Cache.CachedAsset cached = player._server._assets.AssetCache[update.filename];
                        if (cached == null)
                        {                                       //Strange
                            Log.write(TLog.Warning, "Unable to find cache for requested asset '{0}'", update.filename);
                            continue;
                        }

                        //Good, add it to the list
                        SC_AssetUpdateInfo.AssetUpdate assetinfo = new SC_AssetUpdateInfo.AssetUpdate();

                        assetinfo.filename         = update.filename;
                        assetinfo.compressedLength = cached.data.Length;

                        cache.Add(assetinfo);
                    }

                    //Send off our info list!
                    SC_AssetUpdateInfo info = new SC_AssetUpdateInfo();
                    info.updates            = cache;

                    player._client.sendReliable(info);
                }
            }
                );
        }
Exemplo n.º 6
0
        /// <summary>
        /// Looks after the gamestate of all arenas
        /// </summary>
        private void handleArenas()
        {       //Get an image of the arena list
            int          lastArenaUpdate = Environment.TickCount;
            List <Arena> arenas          = new List <Arena>(_arenas.Values);

            while (run)
            {     //Is it time to update our list yet?
                if (Environment.TickCount - lastArenaUpdate > 1000)
                { //Grab a list of arenas
                    using (DdMonitor.Lock(_arenas))
                        arenas = new List <Arena>(_arenas.Values);
                    lastArenaUpdate = Environment.TickCount;
                }

                //Poll each arena!
                foreach (Arena arena in arenas)
                {
                    try
                    {
                        if (arena._bActive)
                        {
                            using (LogAssume.Assume(arena._logger))
                                arena.poll();
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.write(TLog.Exception, "Exception whilst polling arena {0}:\r\n{1}", arena._name, ex);
                    }
                }

                //Poll our base zoneserver
                try
                {
                    this.poll();
                }
                catch (Exception ex)
                {
                    Log.write(TLog.Exception, "Exception whilst polling baseserver: \r\n{0}", ex);
                }

                // Sleep for a bit
                Thread.Sleep(5);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Looks after the gamestate
        /// </summary>
        public void handleState()
        {
            new Thread(() =>
            {
                //Get an image of the arena list
                int lastArenaUpdate = Environment.TickCount;

                while (_bInGame)
                {   //Is it time to update our list yet?
                    if (Environment.TickCount - lastArenaUpdate > 1000)
                    {
                        lastArenaUpdate = Environment.TickCount;


                        try
                        {
                            using (LogAssume.Assume(_logger))
                                _arena.poll();
                        }
                        catch (Exception ex)
                        {
                            Log.write(TLog.Exception, "Exception whilst polling arena {0}:\r\n{1}", _arena._name, ex);
                        }

                        try
                        {
                            using (LogAssume.Assume(_logger))
                                _player.poll();
                        }
                        catch (Exception ex)
                        {
                            Log.write(TLog.Exception, "Exception whilst polling playerstate {0}:\r\n{1}", _arena._name, ex);
                        }
                    }

                    // Sleep for a bit
                    Thread.Sleep(5);
                }
            }).Start();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Looks after our BotState
        /// </summary>
        public void newBot()
        {
            //Instance our Scripting Environment
            ScriptBot scriptBot;

            using (LogAssume.Assume(_logger))
            {
                scriptBot = new ScriptBot(this, _config["General/botScript"].Value);
                scriptBot.init();
            }

            //Start polling our script
            while (true)
            {
                using (LogAssume.Assume(_logger))
                {
                    scriptBot.poll();
                }

                //Sleep for a bit..
                Thread.Sleep(100);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Delegate for asynchronously receiving UDP packets
        /// </summary>
        private void onDataRecieved(IAsyncResult asyn)
        {       //If we're not operating, abort.
            if (!_bOperating)
            {
                return;
            }

            //Use the logger
            using (LogAssume.Assume(_logger))
            {
                PacketBase packet = null;
                byte[]     data   = null;

                try
                {       //Sanity checks
                    if (!asyn.IsCompleted)
                    {   //Abort
                        Log.write(TLog.Warning, "Asynchronous socket operation not completed.");
                        return;
                    }

                    //Receive the data
                    data = _udp.EndReceive(asyn, ref _remEP);
                    int dataLen = data.Length;
                    int offset  = 0;

                    //Read in the typeID
                    ushort typeID = NetworkClient.getTypeID(data, 0);

                    //If our client is inactive, ignore this packet
                    if (!_client._bDestroyed)
                    {   //Make sure the packet is intact
                        if (!_client.checkPacket(data, ref offset, ref dataLen))
                        {
                            //Bad packet!
                            Log.write(TLog.Warning, "Bad packet received from server.");
                        }
                        else
                        {       //Transplant the data into a packet class
                            packet          = _factory.createPacket(_client, typeID, data, offset, dataLen);
                            packet._client  = _client;
                            packet._handler = this;

                            packet.Deserialize();

                            //Queue it up
                            handlePacket(packet, _client);
                            _client._lastPacketRecv = Environment.TickCount;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {       //Socket was closed
                    Log.write(TLog.Inane, "Socket closed.");
                    _bOperating = false;
                    return;
                }
                catch (SocketException se)
                {       //Store the exception and exit
                    if (se.ErrorCode == 10054)
                    {
                        Log.write(TLog.Warning, "Connection to database refused.");
                    }
                    else
                    {
                        Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                    }
                    _bOperating = false;
                    return;
                }
                catch (Exception ex)
                {       //Store the exception and exit
                    Log.write(TLog.Exception, "Exception on recieving data:\r\n{0}", ex.ToString());
                    if (packet != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", packet.DataDump);
                    }
                    else if (data != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", PacketBase.createDataDump(data, 0, data.Length));
                    }
                }

                try
                {       //Wait for more data
                    if (_bOperating)
                    {
                        _udp.BeginReceive(onDataRecieved, null);
                    }
                }
                catch (SocketException se)
                {       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Creates an item drop at the specified location
        /// </summary>
        public void itemSpawn(ItemInfo item, ushort quantity, short positionX, short positionY, Player p)
        {
            using (LogAssume.Assume(_logger))
            {
                if (item == null)
                {
                    Log.write(TLog.Error, "Attempted to spawn invalid item.");
                    return;
                }

                if (quantity == 0)
                {
                    Log.write(TLog.Warning, "Attempted to spawn 0 of an item.");
                    return;
                }

                //Too many items?
                if (_arena._items.Count == Arena.maxItems)
                {
                    Log.write(TLog.Warning, "Item count full.");
                    return;
                }

                int   blockedAttempts = 35;
                short pX;
                short pY;
                while (true)
                {
                    pX = positionX;
                    pY = positionY;
                    Helpers.randomPositionInArea(_arena, _arena._server._zoneConfig.arena.pruneDropRadius, ref pX, ref pY);
                    if (_arena.getTile(pX, pY).Blocked)
                    {
                        blockedAttempts--;
                        if (blockedAttempts <= 0)
                        {
                            //Consider the spawn to be blocked
                            return;
                        }
                        continue;
                    }

                    //We want to continue wrapping around the vehicleid limits
                    //looking for empty spots.
                    ushort ik;

                    for (ik = _arena._lastItemKey; ik <= Int16.MaxValue; ++ik)
                    {   //If we've reached the maximum, wrap around
                        if (ik == Int16.MaxValue)
                        {
                            ik = (ushort)ZoneServer.maxPlayers;
                            continue;
                        }

                        //Does such an item exist?
                        if (_arena._items.ContainsKey(ik))
                        {
                            continue;
                        }

                        //We have a space!
                        break;
                    }

                    _arena._lastItemKey = ik;

                    //Create our drop class
                    Arena.ItemDrop id = new Arena.ItemDrop();

                    id.item       = item;
                    id.id         = ik;
                    id.quantity   = (short)quantity;
                    id.positionX  = pX;
                    id.positionY  = pY;
                    id.relativeID = item.relativeID;
                    id.freq       = -1;

                    id.owner = null; //For bounty abuse upon pickup

                    int expire = _arena.getTerrain(positionX, positionY).prizeExpire;
                    id.tickExpire = (expire > 0 ? (Environment.TickCount + (expire * 1000)) : 0);

                    //Add it to our list
                    _arena._items[ik] = id;

                    //Notify the arena
                    Helpers.Object_ItemDrop(_arena.Players, id);
                    break;
                }
            }
        }
Exemplo n.º 11
0
        public void tryLootDrop(IEnumerable <Player> players, Bot dead, short posX, short posY)
        {
            if (players.Count() == 0)
            {
                return;
            }

            using (LogAssume.Assume(_logger))
            {
                LootTable lootTable = getLootTableByID(dead._type.Id);

                if (lootTable == null)
                {
                    Log.write("Could not find loot table for bot id {0}", dead._type.Id);
                    return;
                }

                int weightRoll = 0;
                //Spawn all of our normal items
                if (lootTable.normalLoot.Count > 0)
                {
                    foreach (LootInfo loot in lootTable.normalLoot)
                    {
                        if (loot._weight >= 100)
                        {
                            itemSpawn(loot._item, (ushort)loot._quantity, posX, posY, null);
                        }
                        else
                        {
                            weightRoll = _rand.Next(0, 100);
                            if (loot._weight >= weightRoll)
                            {
                                itemSpawn(loot._item, (ushort)loot._quantity, posX, posY, null);
                            }
                        }
                    }
                }


                int total    = 0;
                int position = 0;

                total += lootTable.commonChance;
                total += lootTable.uncommonChance;
                total += lootTable.setChance;
                total += lootTable.rareChance;

                Range commonRange = new Range(position, position + lootTable.commonChance);
                position += lootTable.commonChance;
                Range uncommonRange = new Range(position, position + lootTable.uncommonChance);
                position += lootTable.uncommonChance;
                Range setRange = new Range(position, position + lootTable.setChance);
                position += lootTable.setChance;
                Range rareRange = new Range(position, position + lootTable.rareChance);
                position  += lootTable.rareChance;
                weightRoll = 0;
                List <LootInfo> potentialLoot = new List <LootInfo>();
                foreach (Player player in players)
                {
                    Log.write("Trying loot drop for {0}", player._alias);
                    weightRoll = _rand.Next(0, total);

                    Log.write("Category Weight Roll: {0}", weightRoll);

                    if (weightRoll.IsWithin(commonRange.min, commonRange.max))
                    {
                        Log.write("selected commmon loot list");
                        potentialLoot = lootTable.commonLoot;
                    }
                    else if (weightRoll.IsWithin(uncommonRange.min, uncommonRange.max))
                    {
                        Log.write("selected uncommon loot list");
                        potentialLoot = lootTable.uncommonLoot;
                    }
                    else if (weightRoll.IsWithin(setRange.min, setRange.max))
                    {
                        Log.write("selected set loot list");
                        potentialLoot = lootTable.setLoot;
                    }
                    else if (weightRoll.IsWithin(rareRange.min, rareRange.max))
                    {
                        Log.write("selected rare loot list");
                        potentialLoot = lootTable.rareLoot;
                    }
                    else
                    {
                        //No loot for this guy :(
                        if (potentialLoot.Count == 0)
                        {
                            Log.write("no loot list selected");
                            continue;
                        }
                    }



                    int totalLootProbability = 0;
                    int rangePosition        = 0;
                    Dictionary <Range, LootInfo> lootRanges = new Dictionary <Range, LootInfo>();

                    foreach (LootInfo loot in potentialLoot)
                    {
                        totalLootProbability += loot._weight;
                        lootRanges.Add(new Range(rangePosition, rangePosition + loot._weight), loot);
                        rangePosition += loot._weight;
                    }

                    weightRoll = _rand.Next(0, totalLootProbability);
                    Log.write("Item Weight Roll: {0}", weightRoll);
                    LootInfo drop = lootRanges.FirstOrDefault(rng => weightRoll.IsWithin(rng.Key.min, rng.Key.max)).Value;

                    //Better luck next time!
                    if (drop == null)
                    {
                        continue;
                    }

                    //Likely a null item to simulate chance of no drop at all
                    if (drop._item == null)
                    {
                        continue;
                    }

                    //Give the lad his loot!
                    privateItemSpawn(drop._item, (ushort)drop._quantity, dead._state.positionX, dead._state.positionY, player, drop._type, dead, drop._name);
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Creates an item drop at the specified location
        /// </summary>
        public void privateItemSpawn(ItemInfo item, ushort quantity, short positionX, short positionY, Player p, LootType type, Bot dead, string name)
        {
            using (LogAssume.Assume(_logger))
            {
                Log.write("[DROP] - {0} dropped for {1}", item.name, p._alias);

                if (item == null)
                {
                    Log.write(TLog.Error, "Attempted to spawn invalid item.");
                    return;
                }

                if (quantity == 0)
                {
                    Log.write(TLog.Warning, "Attempted to spawn 0 of an item.");
                    return;
                }

                //Too many items?
                if (_arena._items.Count == Arena.maxItems)
                {
                    Log.write(TLog.Warning, "Item count full.");
                    return;
                }

                int            blockedAttempts = 35;
                Arena.ItemDrop spawn           = null;

                short pX;
                short pY;
                while (true)
                {
                    pX = positionX;
                    pY = positionY;
                    Helpers.randomPositionInArea(_arena, _arena._server._zoneConfig.arena.pruneDropRadius, ref pX, ref pY);
                    if (_arena.getTile(pX, pY).Blocked)
                    {
                        blockedAttempts--;
                        if (blockedAttempts <= 0)
                        {
                            //Consider the spawn to be blocked
                            return;
                        }
                        continue;
                    }

                    //We want to continue wrapping around the vehicleid limits
                    //looking for empty spots.
                    ushort ik;

                    for (ik = _arena._lastItemKey; ik <= Int16.MaxValue; ++ik)
                    {   //If we've reached the maximum, wrap around
                        if (ik == Int16.MaxValue)
                        {
                            ik = (ushort)ZoneServer.maxPlayers;
                            continue;
                        }

                        //Does such an item exist?
                        if (_arena._items.ContainsKey(ik))
                        {
                            continue;
                        }

                        //We have a space!
                        break;
                    }



                    _arena._lastItemKey = ik;

                    //Create our drop class
                    Arena.ItemDrop id = new Arena.ItemDrop();

                    id.item       = item;
                    id.id         = ik;
                    id.quantity   = (short)quantity;
                    id.positionX  = pX;
                    id.positionY  = pY;
                    id.relativeID = item.relativeID;
                    id.freq       = p._team._id;

                    id.owner = p; //For bounty abuse upon pickup

                    //Add it to our private loot tracker
                    _script._privateLoot.Add(id.id, new LootDrop(id, p, Environment.TickCount, ik));

                    int expire = _arena.getTerrain(positionX, positionY).prizeExpire;
                    id.tickExpire = (expire > 0 ? (Environment.TickCount + (expire * 1000)) : 0);

                    //Add it to our list
                    _arena._items[ik] = id;
                    //Notify the player
                    Helpers.Object_ItemDrop(_arena.Players, id);


                    if (type > LootType.Common)
                    {
                        foreach (Player player in _arena.Players)
                        {
                            if (player == p)
                            {
                                player.sendMessage(1, String.Format("$A {0} just dropped {1} for you at {2}",
                                                                    dead._type.Name, name, Helpers.posToLetterCoord(id.positionX, id.positionY)));
                            }
                            else
                            {
                                player.triggerMessage(5, 1000, String.Format("A {0} just dropped {1} for {2} at {3}",
                                                                             dead._type.Name, name, p._alias, Helpers.posToLetterCoord(id.positionX, id.positionY)));
                            }
                        }
                    }
                    break;
                }
            }
        }
Exemplo n.º 13
0
 public static void onException(object o, UnhandledExceptionEventArgs e)
 {       //Talk about the exception
     using (LogAssume.Assume(server._logger))
         Log.write(TLog.Exception, "Unhandled exception:\r\n" + e.ExceptionObject.ToString());
 }
Exemplo n.º 14
0
        /// <summary>
        /// Allocates a new player slot for use for entering players
        /// </summary>
        public Player newPlayer(Client <Player> c, string alias)
        {
            using (LogAssume.Assume(_logger))
            {
                //Is there any space?
                if (_players.Count == maxPlayers)
                {
                    Log.write(TLog.Warning, "Server full.");
                    return(null);
                }

                //We want to continue wrapping around the playerid limits
                //looking for empty spots.
                ushort pk;

                for (pk = _lastPlayerKey; pk <= maxPlayers; ++pk)
                {       //If we've reached the maximum, wrap around
                    if (pk == maxPlayers)
                    {
                        pk = 1;
                        continue;
                    }

                    //Does such a player exist?
                    if (_players.ContainsKey(pk))
                    {
                        continue;
                    }

                    //We have a space!
                    break;
                }

                _lastPlayerKey = pk;

                //Create our new player object
                Player newPlayer = new Player();

                c._obj                        = newPlayer;
                newPlayer._client             = c;
                newPlayer._client._playerConn = true;

                newPlayer._id    = pk;
                newPlayer._magic = _rand.Next();

                newPlayer._alias  = alias;
                newPlayer._server = this;

                Log.write(TLog.Normal, "New player: {0} ({1})", newPlayer, newPlayer._client._ipe);

                _players[pk] = newPlayer;

                //Lets setup the players silence list
                if (_playerSilenced.ContainsKey(c._ipe.Address))
                {
                    //Lets check his current silence time
                    int numberKey   = _playerSilenced[c._ipe.Address].Keys.Count;
                    int numberValue = _playerSilenced[c._ipe.Address].Values.Count;
                    if (numberKey > 0)
                    {
                        foreach (int length in _playerSilenced[c._ipe.Address].Keys)
                        {
                            //Lets find the last one then set it
                            newPlayer._lengthOfSilence = length;
                            newPlayer._bSilenced       = true;
                        }
                    }
                    if (numberValue > 0)
                    {
                        foreach (DateTime stamp in _playerSilenced[c._ipe.Address].Values)
                        {
                            newPlayer._timeOfSilence = stamp;
                        }
                    }
                }

                return(newPlayer);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Handles the loss of a player
        /// </summary>
        public void lostPlayer(Player player)
        {
            if (player == null)
            {
                Log.write(TLog.Error, "lostPlayer(): Called with null player.");
                return;
            }
            // find users throttling logins
            // problem: users cannot leave zone and join the same one for 10 seconds
            // add: message informing user to wait so their client won't hang
            try
            {
                if (_connections != null && player._ipAddress != null)
                {
                    if (_connections.ContainsKey((IPAddress)player._ipAddress))
                    {
                        _connections.Remove(player._ipAddress);
                    }
                }
            }
            catch (Exception e)
            {
                Log.write(TLog.Error, e.ToString());
            }
            using (LogAssume.Assume(_logger))
            {                   //Is it present in our list?
                if (!_players.ContainsKey(player._id))
                {               //Notify and discontinue
                    Log.write(TLog.Error, "Lost player '{0}' who wasn't present in the ZoneServer list.", player);
                    return;
                }

                //He's gone!
                _players.Remove(player._id);
                _nameToPlayer.Remove(player._alias);

                Log.write(TLog.Normal, "Lost player: " + player);

                //Disconnect him from the server
                removeClient(player._client);

                //Lets update the players silence list
                if ((_playerSilenced.ContainsKey(player._alias)) && _playerSilenced[player._alias].Keys.Count > 0)
                {
                    int min = 0; DateTime time = DateTime.Now;
                    foreach (int length in _playerSilenced[player._alias].Keys)
                    {
                        min = length;
                    }
                    if (_playerSilenced[player._alias].Values.Count > 0)
                    {
                        foreach (DateTime timer in _playerSilenced[player._alias].Values)
                        {
                            time = timer;
                        }
                    }
                    _playerSilenced.Remove(player._alias);
                    _playerSilenced.Add(player._alias, new Dictionary <int, DateTime>());
                    _playerSilenced[player._alias].Add(min, time);
                }

                //Make sure his stats get updated
                if (player._bDBLoaded && !player._server.IsStandalone)
                {
                    _db.updatePlayer(player);
                }

                //We've lost him!
                if (!player._server.IsStandalone)
                {
                    _db.lostPlayer(player);
                }
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Delegate for asynchronously receiving UDP packets
        /// </summary>
        private void onDataRecieved(IAsyncResult asyn)
        {               //Use the logger
            using (LogAssume.Assume(_logger))
            {
                PacketBase packet = null;
                int        read   = 0;

                try
                {                       //Sanity checks
                    if (!asyn.IsCompleted)
                    {                   //Abort
                        Log.write(TLog.Warning, "Asynchronous socket operation not completed.");
                        return;
                    }

                    //Receive the data
                    read = _sock.EndReceiveFrom(asyn, ref _remEP);

                    //Read in the typeID
                    ushort typeID = NetworkClient.getTypeID(_buffer, 0);

                    //Handle the initial packet specially
                    bool bNewClient = false;

                    //Initial && system packet?
                    if (_buffer[0] == 0 && typeID == Protocol.CS_Initial.TypeID)
                    {                           //If we're receiving the initial packet, then the client will
                                                //want to begin a new connection state. Destroy the old one!
                                                //Protocol.CS_Initial init = packet as Protocol.CS_Initial;
                        bNewClient = true;
                    }

                    //Attempt to find the related NetworkClient
                    _networkLock.AcquireWriterLock(Timeout.Infinite);
                    NetworkClient client = null;

                    try
                    {                           //Form the uid for the client
                        IPEndPoint ipe = (IPEndPoint)_remEP;
                        Int64      id  = ipe.Address.Address | (((Int64)ipe.Port) << 32);

                        //Do we have a client?
                        if (bNewClient)
                        {                               //This client doesn't exist yet, let's create a new class
                            client = _clientTemplate.newInstance();
                            client._lastPacketRecv = Environment.TickCount;
                            client._ipe            = ipe;
                            client._handler        = this;

                            //Add it to our client list
                            _clients[id] = client;
                        }
                        else
                        {
                            _clients.TryGetValue(id, out client);
                        }

                        //Out of sync packet?
                        if (client == null)
                        {
                            Log.write(TLog.Inane, "Out of state packet received from {0}", _remEP);
                        }
                        //If the client is inactive, ignore
                        else if (client._bDestroyed)
                        {
                            client = null;
                        }
                    }
                    finally
                    {                           //Release our lock
                        _networkLock.ReleaseWriterLock();
                    }

                    if (client != null)
                    {                           //Make sure the packet is intact
                        int offset = 0;
                        if (!client.checkPacket(_buffer, ref offset, ref read))
                        {
                            //Bad packet!
                            Log.write(TLog.Warning, "Bad packet received from {0}", client);
                        }
                        else
                        {                               //Transplant the data into a packet class
                            packet          = _factory.createPacket(client, typeID, _buffer, offset, read);
                            packet._client  = client;
                            packet._handler = this;

                            packet.Deserialize();

                            //Queue it up
                            handlePacket(packet, client);
                            client._lastPacketRecv = Environment.TickCount;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {                       //Socket was closed
                    Log.write(TLog.Inane, "Socket closed.");
                    _bOperating = false;
                    return;
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
                catch (Exception ex)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Exception on recieving data:\r\n{0}", ex.ToString());
                    if (packet != null)
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", packet.DataDump);
                    }
                    else
                    {
                        Log.write(TLog.Inane, "Packet data:\r\n{0}", PacketBase.createDataDump(_buffer, 0, read));
                    }
                }

                try
                {                       //Wait for more data
                    _sock.BeginReceiveFrom(_buffer, 0, _buffer.Length, SocketFlags.None, ref _remEP, onDataRecieved, null);
                }
                catch (SocketException se)
                {                       //Store the exception and exit
                    Log.write(TLog.Exception, "Socket exception[{0}]:\r\n{1}", se.ErrorCode, se.ToString());
                }
            }
        }