示例#1
0
        public NewConnectionPacket(NetworkMessage message)
        {
            Os = message.GetUInt16();
            ServiceConfiguration.GetConfiguration().ReceivedClientVersionInt = message.GetUInt16();

            message.SkipBytes(12);
        }
示例#2
0
        /// <summary>
        /// Handles the contents of a network message.
        /// </summary>
        /// <param name="message">The message to handle.</param>
        /// <param name="connection">A reference to the connection from where this message is comming from, for context.</param>
        public override void HandleRequest(INetworkMessage message, IConnection connection)
        {
            var gameConfig   = ServiceConfiguration.GetConfiguration();
            var outXmlString = string.Empty;

            var playersOnline = 0;
            var onlineRecord  = 0;

            using (var otContext = new OpenTibiaDbContext())
            {
                var statusRecord = otContext.Stats.FirstOrDefault();

                if (statusRecord != null)
                {
                    playersOnline = statusRecord.PlayersOnline;
                    onlineRecord  = statusRecord.RecordOnline;
                }
            }

            using (var sw = new StringWriter())
            {
                using (var writer = XmlWriter.Create(sw))
                {
                    writer.WriteStartDocument();
                    writer.WriteAttributeString("version", "1.0");
                    // writer.WriteStartElement("tsqp");
                    // writer.WriteAttributeString("version", "1.0");
                    writer.WriteStartElement("serverinfo");
                    writer.WriteAttributeString("uptime", $"{DateTimeOffset.UtcNow.Ticks}");
                    writer.WriteAttributeString("ip", $"{gameConfig.PublicGameIpAddress}");
                    writer.WriteAttributeString("servername", "OpenTibia");             // TODO: handle multiple game servers. gameConfig.ServerName
                    writer.WriteAttributeString("port", $"{gameConfig.PublicGamePort}");
                    writer.WriteAttributeString("location", gameConfig.LocationString); // TODO: add location to game servers...
                    writer.WriteAttributeString("url", @"http://www.randomot.com");     // TODO: make configurable gameConfig.URL
                    writer.WriteAttributeString("server", "OpenTibia");                 // TODO: handle multiple game servers. gameConfig.ServerName
                    writer.WriteAttributeString("version", "0.1a");                     // TODO: handle. gameConfig.GameVersion
                    writer.WriteAttributeString("client", "7.7");                       // TODO: handle. gameConfig.ClientVersion
                    writer.WriteEndElement();                                           // "serverinfo"
                    writer.WriteStartElement("owner");
                    writer.WriteAttributeString("name", "Gamemaster");                  // TODO: make configurable
                    writer.WriteAttributeString("email", "*****@*****.**");       // TODO: make configurable
                    writer.WriteEndElement();                                           // "owner"
                    writer.WriteStartElement("players");
                    writer.WriteAttributeString("online", $"{playersOnline}");
                    writer.WriteAttributeString("max", $"{gameConfig.MaximumTotalPlayers}");
                    writer.WriteAttributeString("peak", $"{onlineRecord}");
                    writer.WriteEndElement(); // "players"
                    writer.WriteStartElement("motd");
                    writer.WriteString(gameConfig.MessageOfTheDay);
                    writer.WriteEndElement(); // "motd"
                    writer.WriteEndDocument();
                }

                outXmlString = sw.ToString();
            }

            this.ResponsePackets.Add(new ServerStatusPacket(outXmlString));
        }
示例#3
0
        /// <summary>
        /// Handles the contents of a network message.
        /// </summary>
        /// <param name="message">The message to handle.</param>
        /// <param name="connection">A reference to the connection from where this message is comming from, for context.</param>
        public override void HandleRequest(INetworkMessage message, IConnection connection)
        {
            connection.ThrowIfNull(nameof(connection));

            var authInfo = message.ReadAuthenticationInfo();

            var result = authInfo.Password.Equals(ServiceConfiguration.GetConfiguration().QueryManagerPassword);

            connection.IsAuthenticated = result;

            this.ResponsePackets.Add(new AuthenticationResultPacket(!result));
        }
示例#4
0
        /// <summary>
        /// Handles the contents of a network message.
        /// </summary>
        /// <param name="message">The message to handle.</param>
        /// <param name="connection">A reference to the connection from where this message is comming from, for context.</param>
        public override void HandleRequest(INetworkMessage message, IConnection connection)
        {
            // No incoming packet is required to load here.
            var gameConfig = ServiceConfiguration.GetConfiguration();

            this.ResponsePackets.Add(new WorldConfigPacket(
                                         gameConfig.DailyResetHour,
                                         gameConfig.PrivateGameIpAddress.GetAddressBytes(),
                                         gameConfig.MaximumRookgardians,
                                         gameConfig.MaximumTotalPlayers,
                                         gameConfig.PrivateGamePort,
                                         gameConfig.PremiumMainlandBuffer,
                                         gameConfig.PremiumRookgardiansBuffer,
                                         (byte)gameConfig.WorldType));
        }
示例#5
0
        public void HandleMessageContents(NetworkMessage message, Connection connection)
        {
            // No incoming packet is required to load here.
            var gameConfig = ServiceConfiguration.GetConfiguration();

            ResponsePackets.Add(new WorldConfigPacket
            {
                WorldType                 = (byte)gameConfig.WorldType,
                DailyResetHour            = gameConfig.DailyResetHour,
                IpAddressBytes            = gameConfig.PrivateGameIpAddress.GetAddressBytes(),
                Port                      = gameConfig.PrivateGamePort,
                MaximumTotalPlayers       = gameConfig.MaximumTotalPlayers,
                PremiumMainlandBuffer     = gameConfig.PremiumMainlandBuffer,
                MaximumRookgardians       = gameConfig.MaximumRookgardians,
                PremiumRookgardiansBuffer = gameConfig.PremiumRookgardiansBuffer
            });
        }
示例#6
0
        /// <inheritdoc/>
        public override void HandleMessageContents(NetworkMessage message, Connection connection)
        {
            if (connection == null)
            {
                throw new System.ArgumentNullException(nameof(connection));
            }

            var authPacket = new AuthenticationPacket(message);

            var result = authPacket.Password.Equals(ServiceConfiguration.GetConfiguration().QueryManagerPassword);

            connection.IsAuthenticated = result;

            ResponsePackets.Add(new AuthenticationResultPacket {
                HadError = !result
            });
        }
示例#7
0
        /// <summary>
        /// Inserts the command.
        /// </summary>
        /// <param name="command">The command.</param>
        private async Task InsertCommand(Command command)
        {
            var connectionString = ServiceConfiguration.GetConfiguration("DBConnectionString");

            using (
                var conn =
                    new SqlConnection(connectionString)
                )
            {
                var cmd = conn.CreateCommand();
                cmd.CommandText = @"
                    INSERT INTO [dbo].[Command]
                       ([CommandId]
                       ,[CommandTypeId]
                       ,[CommandStatus])
                    VALUES         
                        ('" + command.CommandId + "'," + (int)command.CommandType + ",'Queued')";

                conn.Open();
                await cmd.ExecuteNonQueryAsync().ConfigureAwait(false);
            }
        }
示例#8
0
        public override void ProcessMessage(Connection connection, NetworkMessage inboundMessage)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            if (inboundMessage == null)
            {
                throw new ArgumentNullException(nameof(inboundMessage));
            }

            var packetType = (LoginOrManagementIncomingPacketType)inboundMessage.GetByte();

            if (packetType != LoginOrManagementIncomingPacketType.LoginServerRequest)
            {
                // This packet should NOT have been routed to this protocol.
                Trace.TraceWarning("Non LoginServerRequest packet routed to LoginProtocol. Packet was ignored.");
                return;
            }

            var newConnPacket = new NewConnectionPacket(inboundMessage);
            var gameConfig    = ServiceConfiguration.GetConfiguration();

            if (gameConfig.ReceivedClientVersionInt < gameConfig.ClientMinVersionInt || gameConfig.ReceivedClientVersionInt > gameConfig.ClientMaxVersionInt)
            {
                //ResponsePackets.Add(new GameServerDisconnectPacket {
                //	Reason = $"You need client version in between {gameConfig.ClientMinVersionString} and {gameConfig.ClientMaxVersionString} to connect to this server."
                //});

                return;
            }

            // Make a copy of the message in case we fail to decrypt using the first set of keys.

            var messageCopy = NetworkMessage.Copy(inboundMessage);

            inboundMessage.RsaDecrypt(useRsa2: true);

            if (inboundMessage.GetByte() != 0)
            {
                inboundMessage = messageCopy;

                inboundMessage.RsaDecrypt(useCipKeys: gameConfig.UsingCipsoftRsaKeys);

                if (inboundMessage.GetByte() != 0)                 // means the RSA decrypt was unsuccessful, lets try with the other set of RSA keys...
                {
                    inboundMessage = messageCopy;

                    inboundMessage.RsaDecrypt(useCipKeys: !gameConfig.UsingCipsoftRsaKeys);

                    if (inboundMessage.GetByte() != 0)
                    {
                        // These RSA keys are also unsuccessful... give up.
                        // loginPacket = new AccountLoginPacket(inboundMessage);

                        // connection.SetXtea(loginPacket?.XteaKey);

                        //// TODO: hardcoded messages.
                        // if (gameConfig.UsingCipsoftRSAKeys)
                        // {
                        //    SendDisconnect(connection, $"The RSA encryption keys used by your client cannot communicate with this game server.\nPlease use an IP changer that does not replace the RSA Keys.\nWe recommend using Tibia Loader's 7.7 client.\nYou may also download the client from out website.");
                        // }
                        // else
                        // {
                        //    SendDisconnect(connection, $"The RSA encryption keys used by your client cannot communicate with this game server.\nPlease use an IP changer that replaces the RSA Keys.\nWe recommend using OTLand's IP changer with a virgin 7.7 client.\nYou may also download the client from out website.");
                        // }
                        return;
                    }
                }
            }

            IAccountLoginInfo loginPacket = new AccountLoginPacket(inboundMessage);

            connection.SetXtea(loginPacket.XteaKey);

            using (var otContext = new OpenTibiaDbContext())
            {
                if (!otContext.Users.Any())
                {
                    var u = new User()
                    {
                        Id           = 1,
                        Email        = "1",
                        Login        = 1,
                        Passwd       = "1",
                        Userlevel    = 255,
                        Premium      = 1,
                        Premium_Days = 100
                    };

                    otContext.Users.Add(u);
                    otContext.SaveChanges();

                    var p = new PlayerModel()
                    {
                        Account_Id = 1,
                        Player_Id  = 1,
                        Account_Nr = 1,
                        Charname   = "MUNIZ",
                        Level      = 10,
                        Comment    = "Felipe Muniz"
                    };

                    otContext.Players.Add(p);
                    otContext.SaveChanges();

                    var u2 = new User()
                    {
                        Id           = 2,
                        Email        = "2",
                        Login        = 2,
                        Passwd       = "2",
                        Userlevel    = 50,
                        Premium      = 1,
                        Premium_Days = 100
                    };

                    otContext.Users.Add(u2);
                    otContext.SaveChanges();

                    var p2 = new PlayerModel()
                    {
                        Account_Id = 2,
                        Player_Id  = 2,
                        Account_Nr = 2,
                        Charname   = "FELIPE",
                        Level      = 10,
                        Comment    = "Felipe"
                    };

                    otContext.Players.Add(p2);
                    otContext.SaveChanges();
                }

                // validate credentials.
                var user = otContext.Users.FirstOrDefault(u => u.Login == loginPacket.AccountNumber && u.Passwd.Equals(loginPacket.Password));

                if (user == null)
                {
                    // TODO: hardcoded messages.
                    SendDisconnect(connection, "Please enter a valid account number and password.");
                }
                else
                {
                    var charactersFound = otContext.Players.Where(p => p.Account_Nr == user.Login);

                    if (!charactersFound.Any())
                    {
                        // TODO: hardcoded messages.
                        SendDisconnect(connection, $"Your account does not have any characters.\nPlease create a new character in our web site first: {gameConfig.WebsiteUrl}");
                    }
                    else
                    {
                        var charList = new List <ICharacterListItem>();

                        foreach (var character in charactersFound)
                        {
                            charList.Add(new CharacterListItem(character.Charname, gameConfig.PublicGameIpAddress, gameConfig.PublicGamePort, gameConfig.WorldName));
                        }

                        // TODO: motd
                        SendCharacterList(connection, gameConfig.MessageOfTheDay, (ushort)Math.Min(user.Premium_Days + user.Trial_Premium_Days, ushort.MaxValue), charList);
                    }
                }
            }
        }
示例#9
0
        public override void HandleMessageContents(NetworkMessage message, Connection connection)
        {
            var playerLoginPacket = new PlayerLoginPacket(message);

            connection.SetXtea(playerLoginPacket.XteaKey);

            if (ServiceConfiguration.GetConfiguration().ReceivedClientVersionInt < ServiceConfiguration.GetConfiguration().ClientMinVersionInt ||
                playerLoginPacket.Version > ServiceConfiguration.GetConfiguration().ClientMaxVersionInt)
            {
                ResponsePackets.Add(new GameServerDisconnectPacket {
                    Reason = $"You need client version in between {ServiceConfiguration.GetConfiguration().ClientMinVersionString} and {ServiceConfiguration.GetConfiguration().ClientMaxVersionString} to connect to this server."
                });

                return;
            }

            if (Game.Instance.Status == WorldState.Creating)
            {
                ResponsePackets.Add(new GameServerDisconnectPacket
                {
                    Reason = "The game is just starting.\nPlease try again in a few minutes."
                });

                return;
            }

            using (var otContext = new OpenTibiaDbContext())
            {
                var failure = LoginFailureReason.None;

                var userRecord   = otContext.Users.FirstOrDefault(u => u.Login == playerLoginPacket.AccountNumber && u.Passwd.Equals(playerLoginPacket.Password));
                var playerRecord = otContext.Players.FirstOrDefault(p => p.Account_Nr == playerLoginPacket.AccountNumber && p.Charname.Equals(playerLoginPacket.CharacterName));

                if (userRecord == null || playerRecord == null)
                {
                    failure = LoginFailureReason.AccountOrPasswordIncorrect;
                }
                else
                {
                    // Check bannishment.
                    if (userRecord.Banished > 0 || userRecord.Bandelete > 0)
                    {
                        // Lift if time is up
                        if (userRecord.Bandelete > 0 || DateTime.FromFileTimeUtc(userRecord.Banished_Until) > DateTime.Now)
                        {
                            failure = LoginFailureReason.Bannished;
                        }
                        else
                        {
                            userRecord.Banished = 0;
                        }
                    }

                    // Check that no other characters from this account are logged in.
                    var anotherCharacterIsLoggedIn = otContext.Players.Any(p => p.Account_Nr == playerLoginPacket.AccountNumber && p.Online > 0 && !p.Charname.Equals(playerLoginPacket.CharacterName));

                    if (anotherCharacterIsLoggedIn)
                    {
                        failure = LoginFailureReason.AnotherCharacterIsLoggedIn;
                    }

                    // Check if game is open to public
                    if (Game.Instance.Status != WorldState.Open)
                    {
                        ResponsePackets.Add(new GameServerDisconnectPacket
                        {
                            Reason = "The game is not open to the public yet.\nCheck for news on our webpage."
                        });

                        return;
                    }
                }

                if (failure == LoginFailureReason.None)
                {
                    try
                    {
                        // Set player status to online.
                        // playerRecord.online = 1;

                        // otContext.SaveChanges();
                        var player = Game.Instance.Login(playerRecord, connection);

                        // set this to allow future packets from this connection.
                        connection.IsAuthenticated = true;
                        connection.PlayerId        = player.CreatureId;

                        ResponsePackets.Add(new SelfAppearPacket
                        {
                            CreatureId = player.CreatureId,
                            IsLogin    = true,
                            Player     = player
                        });

                        // Add MapDescription
                        ResponsePackets.Add(new MapDescriptionPacket
                        {
                            Origin           = player.Location,
                            DescriptionBytes = Game.Instance.GetMapDescriptionAt(player, player.Location)
                        });

                        ResponsePackets.Add(new MagicEffectPacket
                        {
                            Location = player.Location,
                            Effect   = EffectT.BubbleBlue
                        });

                        ResponsePackets.Add(new PlayerInventoryPacket {
                            Player = player
                        });
                        ResponsePackets.Add(new PlayerStatusPacket {
                            Player = player
                        });
                        ResponsePackets.Add(new PlayerSkillsPacket {
                            Player = player
                        });

                        ResponsePackets.Add(new WorldLightPacket {
                            Level = Game.Instance.LightLevel, Color = Game.Instance.LightColor
                        });

                        ResponsePackets.Add(new CreatureLightPacket {
                            Creature = player
                        });

                        // Adds a text message
                        ResponsePackets.Add(new TextMessagePacket
                        {
                            Type    = MessageType.StatusDefault,
                            Message = "This is a test message"
                        });

                        // std::string tempstring = g_config.getString(ConfigManager::LOGIN_MSG);
                        // if (tempstring.size() > 0)
                        // {
                        //    AddTextMessage(msg, MSG_STATUS_DEFAULT, tempstring.c_str());
                        // }

                        // if (player->getLastLoginSaved() != 0)
                        // {
                        //    tempstring = "Your last visit was on ";
                        //    time_t lastLogin = player->getLastLoginSaved();
                        //    tempstring += ctime(&lastLogin);
                        //    tempstring.erase(tempstring.length() - 1);
                        //    tempstring += ".";

                        // AddTextMessage(msg, MSG_STATUS_DEFAULT, tempstring.c_str());
                        // }
                        // else
                        // {
                        //    tempstring = "Welcome to ";
                        //    tempstring += g_config.getString(ConfigManager::SERVER_NAME);
                        //    tempstring += ". Please choose an outfit.";
                        //    sendOutfitWindow(player);
                        // }

                        // Add any Vips here.

                        // for (VIPListSet::iterator it = player->VIPList.begin(); it != player->VIPList.end(); it++)
                        // {
                        //    bool online;
                        //    std::string vip_name;
                        //    if (IOPlayer::instance()->getNameByGuid((*it), vip_name))
                        //    {
                        //        online = (g_game.getPlayerByName(vip_name) != NULL);
                        //
                        // msg->AddByte(0xD2);
                        // msg->AddU32(guid);
                        // msg->AddString(name);
                        // msg->AddByte(isOnline ? 1 : 0);
                        //    }
                        // }

                        // Send condition icons
                        ResponsePackets.Add(new PlayerConditionsPacket {
                            Player = player
                        });

                        return;
                    }
                    catch (Exception ex)
                    {
                        // TODO: propper logging
                        Console.WriteLine(ex);

                        failure = LoginFailureReason.InternalServerError;
                    }
                }

                if (failure != LoginFailureReason.None)
                {
                    ResponsePackets.Add(new GameServerDisconnectPacket
                    {
                        Reason = failure.ToString() // TODO: implement correctly.
                    });
                }
            }
        }
示例#10
0
 // GET api/configuration/5
 public ServiceConfig Get(int id)
 {
     return(ServiceConfiguration.GetConfiguration(id));
 }
示例#11
0
        public override void ProcessMessage(Connection connection, NetworkMessage inboundMessage)
        {
            if (connection == null)
            {
                throw new ArgumentNullException(nameof(connection));
            }

            if (inboundMessage == null)
            {
                throw new ArgumentNullException(nameof(inboundMessage));
            }

            byte packetType;

            if (!connection.IsAuthenticated || connection.XTeaKey.Sum(b => b) == 0)
            {
                // this is a new connection...
                packetType = inboundMessage.GetByte();

                if (packetType != (byte)GameIncomingPacketType.PlayerLoginRequest)
                {
                    // but this is not the packet we were expecting for a new connection.
                    connection.Close();
                    return;
                }

                //if (ServiceConfiguration.GetConfiguration().ReceivedClientVersionInt > 770) {
                var os = inboundMessage.GetUInt16();
                ServiceConfiguration.GetConfiguration().ReceivedClientVersionInt = inboundMessage.GetUInt16();
                //}


                var gameConfig = ServiceConfiguration.GetConfiguration();

                // Make a copy of the message in case we fail to decrypt using the first set of keys.
                var messageCopy = NetworkMessage.Copy(inboundMessage);

                inboundMessage.RsaDecrypt(useRsa2: true);

                if (inboundMessage.GetByte() != 0)
                {
                    // means the RSA decrypt was unsuccessful, lets try with the other set of RSA keys...
                    inboundMessage = messageCopy;

                    inboundMessage.RsaDecrypt(useCipKeys: gameConfig.UsingCipsoftRsaKeys);

                    if (inboundMessage.GetByte() != 0)
                    {
                        // means the RSA decrypt was unsuccessful, lets try with the other set of RSA keys...
                        inboundMessage = messageCopy;
                        inboundMessage.RsaDecrypt(useCipKeys: !gameConfig.UsingCipsoftRsaKeys);

                        if (inboundMessage.GetByte() != 0)
                        {
                            // These RSA keys are also usuccessful... so give up.
                            connection.Close();
                            return;
                        }
                    }
                }
            }
            else
            {
                // Decrypt message using XTea
                inboundMessage.XteaDecrypt(connection.XTeaKey);
                inboundMessage.GetUInt16();
                packetType = inboundMessage.GetByte();
            }

            var handler = HandlerFactory.CreateIncommingForType(packetType);

            handler?.HandleMessageContents(inboundMessage, connection);

            if (handler?.ResponsePackets != null && handler.ResponsePackets.Any())
            {
                // Send any responses prepared for
                var message = new NetworkMessage(4);

                foreach (var outPacket in handler.ResponsePackets)
                {
                    message.AddPacket(outPacket);
                }

                connection.Send(message);
            }
        }