Beispiel #1
0
        public void AddItem(int x, int y, ItemObject itemObject)
        {
            GameLog.DebugFormat("{0}, {1}, {2} qty {3} id {4}",
                                x, y, itemObject.Name, itemObject.Count, itemObject.Id);
            if (itemObject.Id == 0)
            {
                World.Insert(itemObject);
            }

            if (itemObject == null)
            {
                GameLog.DebugFormat("ItemObject is null, aborting");
                return;
            }
            // Add the ItemObject to the world at the given location.
            itemObject.X   = (byte)x;
            itemObject.Y   = (byte)y;
            itemObject.Map = this;
            lock (_lock)
            {
                EntityTree.Add(itemObject);
                Objects.Add(itemObject);
            }
            NotifyNearbyAoiEntry(itemObject);
        }
Beispiel #2
0
        public bool Use(User target)
        {
            GameLog.DebugFormat("warp: {0} from {1} ({2},{3}) to {4} ({5}, {6}", target.Name, SourceMap.Name, X, Y,
                                DestinationMapName, DestinationX, DestinationY);
            switch (WarpType)
            {
            case WarpType.Map:
                Map map;
                if (SourceMap.World.WorldData.TryGetValueByIndex(DestinationMapName, out map))
                {
                    target.Teleport(map.Id, DestinationX, DestinationY);
                    return(true);
                }
                GameLog.ErrorFormat("User {0} tried to warp to nonexistent map {1} from {2}: {3},{4}", target.Name,
                                    DestinationMapName, SourceMap.Name, X, Y);
                break;

            case WarpType.WorldMap:
                WorldMap wmap;
                if (SourceMap.World.WorldData.TryGetValue(DestinationMapName, out wmap))
                {
                    SourceMap.Remove(target);
                    target.SendWorldMap(wmap);
                    SourceMap.World.WorldData.Get <Map>(Hybrasyl.Constants.LAG_MAP).Insert(target, 5, 5, false);
                    return(true);
                }
                GameLog.ErrorFormat("User {0} tried to warp to nonexistent worldmap {1} from {2}: {3},{4}",
                                    target.Name,
                                    DestinationMapName, SourceMap.Name, X, Y);
                break;
            }
            return(false);
        }
Beispiel #3
0
        private void ControlMessage_SpawnMonster(HybrasylControlMessage message)
        {
            var monster = (Monster)message.Arguments[0];
            var map     = (Map)message.Arguments[1];

            GameLog.DebugFormat("monolith: spawning monster {0} on map {1}", monster.Name, map.Name);
            map.InsertCreature(monster);
        }
Beispiel #4
0
        private void PacketHandler_0x03_Login(Client client, ClientPacket packet)
        {
            var name     = packet.ReadString8();
            var password = packet.ReadString8();

            GameLog.DebugFormat("cid {0}: Login request for {1}", client.ConnectionId, name);

            if (!World.PlayerExists(name))
            {
                client.LoginMessage("That character does not exist", 3);
                GameLog.InfoFormat("cid {0}: attempt to login as nonexistent character {1}", client.ConnectionId, name);
                return;
            }

            if (World.TryGetUser(name, out User loginUser))
            {
                if (loginUser.VerifyPassword(password))
                {
                    GameLog.DebugFormat("cid {0}: password verified for {1}", client.ConnectionId, name);

                    if (Game.World.WorldData.ContainsKey <User>(name))
                    {
                        GameLog.InfoFormat("cid {0}: {1} logging on again, disconnecting previous connection",
                                           client.ConnectionId, name);
                        client.LoginMessage("That character is already online. Please try again.", 3);
                        World.ControlMessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.LogoffUser, name));
                        return;
                    }

                    GameLog.DebugFormat("cid {0} ({1}): logging in", client.ConnectionId, name);
                    client.LoginMessage("\0", 0);
                    client.SendMessage("Welcome to Hybrasyl!", 3);
                    GameLog.DebugFormat("cid {0} ({1}): sending redirect to world", client.ConnectionId, name);

                    var redirect = new Redirect(client, this, Game.World, name, client.EncryptionSeed,
                                                client.EncryptionKey);
                    GameLog.InfoFormat("cid {0} ({1}): login successful, redirecting to world server",
                                       client.ConnectionId, name);
                    loginUser.Login.LastLogin     = DateTime.Now;
                    loginUser.Login.LastLoginFrom = ((IPEndPoint)client.Socket.RemoteEndPoint).Address.ToString();
                    loginUser.Save();
                    client.Redirect(redirect);
                }
                else
                {
                    GameLog.WarningFormat("cid {0} ({1}): password incorrect", client.ConnectionId, name);
                    client.LoginMessage("Incorrect password", 3);
                    loginUser.Login.LastLoginFailure = DateTime.Now;
                    loginUser.Login.LoginFailureCount++;
                    loginUser.Save();
                }
            }
            else
            {
                // Something bad has happened
                client.LoginMessage("An unknown error occurred. Please contact Hybrasyl support.", 3);
            }
        }
Beispiel #5
0
        public virtual void AcceptConnection(IAsyncResult ar)
        {
            // TODO: @norrismiv async callbacks+inheritance? and/or can these callbacks suck less?
            AllDone.Set();
            if (!Active)
            {
                return;
            }
            Socket handler;
            Socket clientSocket;

            try
            {
                clientSocket = (Socket)ar.AsyncState;
                handler      = clientSocket.EndAccept(ar);
            }
            catch (ObjectDisposedException e)
            {
                GameLog.Error($"Disposed socket {e.Message}");
                return;
            }
            Client client = new Client(handler, this);

            Clients.TryAdd(handler.Handle, client);
            GlobalConnectionManifest.RegisterClient(client);

            if (this is Lobby)
            {
                var x7E = new ServerPacket(0x7E);
                x7E.WriteByte(0x1B);
                x7E.WriteString("CONNECTED SERVER\n");
                client.Enqueue(x7E);
                GameLog.DebugFormat("Lobby: AcceptConnection occuring");
                GameLog.DebugFormat("Lobby: cid is {0}", client.ConnectionId);
            }
            else if (this is Login)
            {
                GameLog.DebugFormat("Login: AcceptConnection occuring");
                GameLog.DebugFormat("Login: cid is {0}", client.ConnectionId);
            }
            else if (this is World)
            {
                GameLog.DebugFormat("World: AcceptConnection occuring");
                GameLog.DebugFormat("World: cid is {0}", client.ConnectionId);
            }
            try
            {
                handler.BeginReceive(client.ClientState.Buffer, 0, client.ClientState.Buffer.Length, 0,
                                     new AsyncCallback(ReadCallback), client.ClientState);
                GameLog.DebugFormat("AcceptConnection returning");
                clientSocket.BeginAccept(new AsyncCallback(AcceptConnection), clientSocket);
            }
            catch (SocketException e)
            {
                Game.ReportException(e);
                handler.Close();
            }
        }
Beispiel #6
0
 public void Enqueue(ClientPacket packet)
 {
     GameLog.DebugFormat("Enqueueing ClientPacket {0}", packet.Opcode);
     ClientState.ReceiveBufferAdd(packet);
     if (!packet.ShouldEncrypt || (packet.ShouldEncrypt && EncryptionKey != null))
     {
         FlushReceiveBuffer();
     }
 }
Beispiel #7
0
        public bool Load()
        {
            IsWall = new bool[X, Y];
            var filename = Path.Combine(World.MapFileDirectory, $"lod{Id}.map");

            if (File.Exists(filename))
            {
                RawData  = File.ReadAllBytes(filename);
                Checksum = Crc16.Calculate(RawData);

                int index = 0;
                for (int y = 0; y < Y; ++y)
                {
                    for (int x = 0; x < X; ++x)
                    {
                        var bg  = RawData[index++] | RawData[index++] << 8;
                        var lfg = RawData[index++] | RawData[index++] << 8;
                        var rfg = RawData[index++] | RawData[index++] << 8;

                        if (lfg != 0 && (Game.Collisions[lfg - 1] & 0x0F) == 0x0F)
                        {
                            IsWall[x, y] = true;
                        }

                        if (rfg != 0 && (Game.Collisions[rfg - 1] & 0x0F) == 0x0F)
                        {
                            IsWall[x, y] = true;
                        }

                        ushort lfgu = (ushort)lfg;
                        ushort rfgu = (ushort)rfg;

                        if (Game.DoorSprites.ContainsKey(lfgu))
                        {
                            // This is a left-right door
                            GameLog.DebugFormat("Inserting LR door at {0}@{1},{2}: Collision: {3}",
                                                Name, x, y, IsWall[x, y]);

                            InsertDoor((byte)x, (byte)y, IsWall[x, y], true,
                                       Game.IsDoorCollision(lfgu));
                        }
                        else if (Game.DoorSprites.ContainsKey(rfgu))
                        {
                            GameLog.DebugFormat("Inserting UD door at {0}@{1},{2}: Collision: {3}",
                                                Name, x, y, IsWall[x, y]);
                            // THis is an up-down door
                            InsertDoor((byte)x, (byte)y, IsWall[x, y], false,
                                       Game.IsDoorCollision(rfgu));
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
Beispiel #8
0
 /// <summary>
 /// Atomically update the last time we received a packet (in ticks).
 /// This also automatically marks the client as not idle.
 /// </summary>
 public void UpdateLastReceived(bool updateIdle = true)
 {
     Interlocked.Exchange(ref _lastReceived, DateTime.Now.Ticks);
     if (updateIdle)
     {
         Interlocked.Exchange(ref _idle, 0);
     }
     GameLog.DebugFormat("cid {0}: lastReceived now {1}", ConnectionId, _lastReceived);
 }
Beispiel #9
0
 public void RemoveItem(ItemObject itemObject)
 {
     // Remove the ItemObject from the world at the specified location.
     GameLog.DebugFormat("Removing {0} qty {1} id {2}", itemObject.Name, itemObject.Count, itemObject.Id);
     NotifyNearbyAoiDeparture(itemObject);
     lock (_lock)
     {
         EntityTree.Remove(itemObject);
         Objects.Remove(itemObject);
     }
 }
Beispiel #10
0
 public void RemoveGold(Gold gold)
 {
     // Remove the gold from the world at the specified location.
     GameLog.DebugFormat("Removing {0} qty {1} id {2}", gold.Name, gold.Amount, gold.Id);
     NotifyNearbyAoiDeparture(gold);
     lock (_lock)
     {
         EntityTree.Remove(gold);
         Objects.Remove(gold);
     }
     World.Remove(gold);
 }
Beispiel #11
0
 public void Enqueue(ServerPacket packet)
 {
     GameLog.DebugFormat("Enqueueing ServerPacket {0}", packet.Opcode);
     if (!Connected)
     {
         Disconnect();
         throw new ObjectDisposedException($"cid {ConnectionId}");
     }
     else
     {
         ClientState.SendBufferAdd(packet);
     }
 }
Beispiel #12
0
 public Server(int port)
 {
     Clients                = new ConcurrentDictionary <IntPtr, Client>();
     Port                   = port;
     PacketHandlers         = new WorldPacketHandler[256];
     ControlMessageHandlers = new ControlMessageHandler[64];
     Throttles              = new Dictionary <byte, IPacketThrottle>();
     ExpectedConnections    = new ConcurrentDictionary <uint, Redirect>();
     for (int i = 0; i < 256; ++i)
     {
         PacketHandlers[i] = (c, p) => GameLog.DebugFormat("Server: Unhandled opcode 0x{0:X2}", p.Opcode);
     }
 }
Beispiel #13
0
 public void NotifyNearbyAoiEntry(VisibleObject objectToAdd)
 {
     foreach (var obj in EntityTree.GetObjects(objectToAdd.GetViewport()))
     {
         if (obj is User)
         {
             GameLog.DebugFormat("Notifying {0} of object {1} at {2},{3} with sprite {4}", obj.Name, objectToAdd.Name,
                                 objectToAdd.X, objectToAdd.Y, objectToAdd.Sprite);
             var user = obj as User;
             user.AoiEntry(objectToAdd);
         }
     }
 }
Beispiel #14
0
        /// <summary>
        /// Check to see if a client is idle
        /// </summary>
        public void CheckIdle()
        {
            var now      = DateTime.Now.Ticks;
            var idletime = new TimeSpan(now - _lastReceived);

            if (idletime.TotalSeconds > Constants.IDLE_TIME)
            {
                GameLog.DebugFormat("cid {0}: idle for {1} seconds, marking as idle", ConnectionId, idletime.TotalSeconds);
                ToggleIdle();
                GameLog.DebugFormat("cid {0}: ToggleIdle: {1}", ConnectionId, IsIdle());
            }
            else
            {
                GameLog.DebugFormat("cid {0}: idle for {1} seconds, not idle", ConnectionId, idletime.TotalSeconds);
            }
        }
Beispiel #15
0
 public void Enqueue(ClientPacket packet)
 {
     GameLog.DebugFormat("Enqueueing ClientPacket {0}", packet.Opcode);
     if (!Connected)
     {
         Disconnect();
         throw new ObjectDisposedException($"cid {ConnectionId}");
     }
     else
     {
         ClientState.ReceiveBufferAdd(packet);
         if (!packet.ShouldEncrypt || (packet.ShouldEncrypt && EncryptionKey != null))
         {
             FlushReceiveBuffer();
         }
     }
 }
Beispiel #16
0
 public void AddGold(int x, int y, Gold gold)
 {
     GameLog.DebugFormat("{0}, {1}, {2} qty {3} id {4}",
                         x, y, gold.Name, gold.Amount, gold.Id);
     if (gold == null)
     {
         GameLog.DebugFormat("ItemObject is null, aborting");
         return;
     }
     // Add the gold to the world at the given location.
     gold.X   = (byte)x;
     gold.Y   = (byte)y;
     gold.Map = this;
     lock (_lock)
     {
         EntityTree.Add(gold);
         Objects.Add(gold);
     }
     NotifyNearbyAoiEntry(gold);
 }
Beispiel #17
0
 private void ContinueReceiving(ClientState state, Client client)
 {
     // Continue getting dem bytes
     try
     {
         state.WorkSocket.BeginReceive(state.Buffer, state.BytesReceived, state.Buffer.Length - state.BytesReceived, 0,
                                       new AsyncCallback(this.ReadCallback), state);
         GameLog.DebugFormat("Triggering receive callback");
     }
     catch (ObjectDisposedException e)
     {
         GameLog.Fatal(e.Message);
         //client.Disconnect();
         state.WorkSocket.Close();
     }
     catch (SocketException e)
     {
         GameLog.Fatal(e.Message);
         client.Disconnect();
     }
 }
Beispiel #18
0
        public void SendCallback(IAsyncResult ar)
        {
            ClientState state = (ClientState)ar.AsyncState;
            Client      client;

            GameLog.DebugFormat($"EndSend: SocketConnected: {state.WorkSocket.Connected}, IAsyncResult: Completed: {ar.IsCompleted}, CompletedSynchronously: {ar.CompletedSynchronously}");

            try
            {
                SocketError errorCode;
                var         bytesSent = state.WorkSocket.EndSend(ar, out errorCode);
                if (!GlobalConnectionManifest.ConnectedClients.TryGetValue(state.Id, out client))
                {
                    GameLog.ErrorFormat("Send: socket should not exist: cid {0}", state.Id);
                    state.WorkSocket.Close();
                    state.WorkSocket.Dispose();
                    return;
                }

                if (bytesSent == 0 || errorCode != SocketError.Success)
                {
                    GameLog.ErrorFormat("cid {0}: disconnected");
                    client.Disconnect();
                    throw new SocketException((int)errorCode);
                }
            }
            catch (SocketException e)
            {
                Game.ReportException(e);
                GameLog.Error($"Error Code: {e.ErrorCode}, {e.Message}");
                state.WorkSocket.Close();
            }
            catch (ObjectDisposedException)
            {
                //client.Disconnect();
                GameLog.Error($"ObjectDisposedException");
                state.WorkSocket.Close();
            }
            state.SendComplete.Set();
        }
Beispiel #19
0
        /// <summary>
        /// Toggle a given door's state (open/closed) and send updates to users nearby.
        /// </summary>
        /// <param name="x">The X coordinate of the door.</param>
        /// <param name="y">The Y coordinate of the door.</param>
        /// <returns></returns>
        public void ToggleDoor(byte x, byte y)
        {
            var coords = new Tuple <byte, byte>(x, y);

            GameLog.DebugFormat("Door {0}@{1},{2}: Open: {3}, changing to {4}",
                                Name, x, y, Doors[coords].Closed,
                                !Doors[coords].Closed);

            Doors[coords].Closed = !Doors[coords].Closed;

            // There are several examples of doors in Temuair that trigger graphic
            // changes but do not trigger collision updates (e.g. 3-panel doors in
            // Piet & Undine).
            if (Doors[coords].UpdateCollision)
            {
                GameLog.DebugFormat("Door {0}@{1},{2}: updateCollision is set, collisions are now {3}",
                                    Name, x, y, !Doors[coords].Closed);
                IsWall[x, y] = !IsWall[x, y];
            }

            GameLog.DebugFormat("Toggling door at {0},{1}", x, y);
            GameLog.DebugFormat("Door is now in state: Open: {0} Collision: {1}", Doors[coords].Closed, IsWall[x, y]);

            var updateViewport = GetViewport(x, y);

            foreach (var obj in EntityTree.GetObjects(updateViewport))
            {
                if (obj is User)
                {
                    var user = obj as User;
                    GameLog.DebugFormat("Sending door packet to {0}: X {1}, Y {2}, Open {3}, LR {4}",
                                        user.Name, x, y, Doors[coords].Closed,
                                        Doors[coords].IsLeftRight);

                    user.SendDoorUpdate(x, y, Doors[coords].Closed,
                                        Doors[coords].IsLeftRight);
                }
            }
        }
Beispiel #20
0
        public byte[] GetBytes()
        {
            var buffer = Encoding.ASCII.GetBytes(Name);

            GameLog.DebugFormat("buffer is {0} and Name is {1}", BitConverter.ToString(buffer), Name);

            // X quadrant, offset, Y quadrant, offset, length of the name, the name, plus a 64-bit(?!) ID
            var bytes = new List <Byte>();

            GameLog.DebugFormat("{0}, {1}, {2}, {3}, {4}, mappoint ID is {5}", XQuadrant, XOffset, YQuadrant,
                                YOffset, Name.Length, Id);

            bytes.Add((byte)XQuadrant);
            bytes.Add((byte)XOffset);
            bytes.Add((byte)YQuadrant);
            bytes.Add((byte)YOffset);
            bytes.Add((byte)Name.Length);
            bytes.AddRange(buffer);
            bytes.AddRange(BitConverter.GetBytes(Id));

            return(bytes.ToArray());
        }
Beispiel #21
0
        /// <summary>
        /// Determine whether either heartbeat has "expired" (meaning REAP_HEARTBEAT_INTERVAL has
        /// passed since we received a heartbeat response).
        /// </summary>
        /// <returns>True or false, indicating expiration.</returns>
        public bool IsHeartbeatExpired()
        {
            // If we have no record of sending a heartbeat, obviously it hasn't expired
            if (_tickHeartbeatSent == 0 && _byteHeartbeatSent == 0)
            {
                return(false);
            }

            var tickSpan = new TimeSpan(_tickHeartbeatReceived - _tickHeartbeatSent);
            var byteSpan = new TimeSpan(_byteHeartbeatReceived - _byteHeartbeatSent);

            GameLog.DebugFormat("cid {0}: tick heartbeat elapsed seconds {1}, byte heartbeat elapsed seconds {2}",
                                ConnectionId, tickSpan.TotalSeconds, byteSpan.TotalSeconds);

            if (tickSpan.TotalSeconds > Constants.REAP_HEARTBEAT_INTERVAL ||
                byteSpan.TotalSeconds > Constants.REAP_HEARTBEAT_INTERVAL)
            {
                // DON'T FEAR THE REAPER
                GameLog.InfoFormat("cid {0}: heartbeat expired", ConnectionId);
                return(true);
            }
            return(false);
        }
Beispiel #22
0
        public byte[] GetBytes()
        {
            // Returns the representation of the worldmap as an array of bytes,
            // suitable to passing to a map packet.

            var buffer = Encoding.ASCII.GetBytes(ClientMap);
            var bytes  = new List <Byte> {
                (byte)ClientMap.Length
            };

            bytes.AddRange(buffer);
            bytes.Add((byte)Points.Count);
            bytes.Add(0x00);

            foreach (var mappoint in Points)
            {
                bytes.AddRange(mappoint.GetBytes());
            }

            GameLog.DebugFormat("I am sending the following map packet:");
            GameLog.DebugFormat("{0}", BitConverter.ToString(bytes.ToArray()));

            return(bytes.ToArray());
        }
Beispiel #23
0
 public void InsertCreature(Creature toInsert)
 {
     World.Insert(toInsert);
     Insert(toInsert, toInsert.X, toInsert.Y);
     GameLog.DebugFormat("Monster {0} with id {1} spawned.", toInsert.Name, toInsert.Id);
 }
Beispiel #24
0
        public void FlushReceiveBuffer()
        {
            lock (ClientState.ReceiveLock)
            {
                try
                {
                    ClientPacket packet;
                    while (ClientState.ReceiveBufferTake(out packet))
                    {
                        if (packet.ShouldEncrypt)
                        {
                            packet.Decrypt(this);
                        }

                        if (packet.Opcode == 0x39 || packet.Opcode == 0x3A)
                        {
                            packet.DecryptDialog();
                        }
                        try
                        {
                            if (Server is Lobby)
                            {
                                GameLog.DebugFormat("Lobby: 0x{0:X2}", packet.Opcode);
                                var handler = (Server as Lobby).PacketHandlers[packet.Opcode];
                                handler.Invoke(this, packet);
                                GameLog.DebugFormat("Lobby packet done");
                                UpdateLastReceived();
                            }
                            else if (Server is Login)
                            {
                                GameLog.Debug($"Login: 0x{packet.Opcode:X2}");
                                var handler = (Server as Login).PacketHandlers[packet.Opcode];
                                handler.Invoke(this, packet);
                                GameLog.DebugFormat("Login packet done");
                                UpdateLastReceived();
                            }
                            else
                            {
                                UpdateLastReceived(packet.Opcode != 0x45 &&
                                                   packet.Opcode != 0x75);
                                GameLog.Debug($"Queuing: 0x{packet.Opcode:X2}");
                                //packet.DumpPacket();
                                // Check for throttling
                                var throttleResult = Server.PacketThrottleCheck(this, packet);
                                if (throttleResult == ThrottleResult.OK || throttleResult == ThrottleResult.ThrottleEnd || throttleResult == ThrottleResult.SquelchEnd)
                                {
                                    World.MessageQueue.Add(new HybrasylClientMessage(packet, ConnectionId));
                                }
                                else
                                if (packet.Opcode == 0x06)
                                {
                                    World.ControlMessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.TriggerRefresh, ConnectionId));
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            Game.ReportException(e);
                            GameLog.ErrorFormat("EXCEPTION IN HANDLING: 0x{0:X2}: {1}", packet.Opcode, e);
                        }
                    }
                }
                catch (Exception e)
                {
                    Game.ReportException(e);
                    Console.WriteLine(e);
                    throw;
                }
            }
        }
Beispiel #25
0
 public void RemoveCreature(Creature toRemove)
 {
     World.Remove(toRemove);
     Remove(toRemove);
     GameLog.DebugFormat("Removing creature {0} (id {1})", toRemove.Name, toRemove.Id);
 }
Beispiel #26
0
 public void DumpPacket()
 {
     // Dump the packet to the console.
     GameLog.DebugFormat("Dumping packet:");
     GameLog.DebugFormat(BitConverter.ToString(Data));
 }