Esempio n. 1
0
        /// <summary>
        /// Handles the zone login request packet
        /// </summary>
        static public void Handle_CS_PlayerLogin(CS_PlayerLogin <Zone> pkt, Zone zone)
        {       //Make a note
            Log.write(TLog.Inane, "Player login request for '{0}' on '{1}'", pkt.alias, zone);

            SC_PlayerLogin <Zone> plog = new SC_PlayerLogin <Zone>();

            plog.player = pkt.player;

            if (String.IsNullOrWhiteSpace(pkt.alias))
            {
                plog.bSuccess     = false;
                plog.loginMessage = "Please enter an alias.";

                zone._client.send(plog);
                return;
            }

            //Are they using the launcher?
            if (String.IsNullOrWhiteSpace(pkt.ticketid))
            {   //They're trying to trick us, jim!
                plog.bSuccess     = false;
                plog.loginMessage = "Please use the Infantry launcher to run the game.";

                zone._client.send(plog);
                return;
            }

            if (pkt.ticketid.Contains(':'))
            {   //They're using the old, outdated launcher
                plog.bSuccess     = false;
                plog.loginMessage = "Please use the updated launcher from the website.";

                zone._client.send(plog);
                return;
            }


            using (InfantryDataContext db = zone._server.getContext())
            {
                Data.DB.player  player  = null;
                Data.DB.account account = db.accounts.SingleOrDefault(acct => acct.ticket.Equals(pkt.ticketid));

                if (account == null)
                {       //They're trying to trick us, jim!
                    plog.bSuccess     = false;
                    plog.loginMessage = "Your session id has expired. Please re-login.";

                    zone._client.send(plog);
                    return;
                }

                //Is there already a player online under this account?
                if (!DBServer.bAllowMulticlienting && zone._server._zones.Any(z => z.hasAccountPlayer(account.id)))
                {
                    plog.bSuccess     = false;
                    plog.loginMessage = "Account is currently in use.";

                    zone._client.send(plog);
                    return;
                }

                //Check for IP and UID bans
                Logic_Bans.Ban banned = Logic_Bans.checkBan(pkt, db, account, zone._zone.id);

                if (banned.type == Logic_Bans.Ban.BanType.GlobalBan)
                {   //We don't respond to globally banned player requests
                    plog.bSuccess     = false;
                    plog.loginMessage = "Banned.";

                    Log.write(TLog.Warning, "Failed login: "******" Alias: " + pkt.alias + " Reason: " + banned.type.ToString());
                    zone._client.send(plog);
                    return;
                }

                if (banned.type == Logic_Bans.Ban.BanType.IPBan)
                {   //Their IP has been banned, make something up!
                    plog.bSuccess     = false;
                    plog.loginMessage = "You have been temporarily suspended until " + banned.expiration.ToString("f", CultureInfo.CreateSpecificCulture("en-US"));

                    Log.write(TLog.Warning, "Failed login: "******" Alias: " + pkt.alias + " Reason: " + banned.type.ToString());
                    zone._client.send(plog);
                    return;
                }

                if (banned.type == Logic.Logic_Bans.Ban.BanType.ZoneBan)
                {   //They've been blocked from entering the zone, tell them how long they've got left on their ban
                    plog.bSuccess     = false;
                    plog.loginMessage = "You have been temporarily suspended from this zone until " + banned.expiration.ToString("f", CultureInfo.CreateSpecificCulture("en-US"));

                    Log.write(TLog.Warning, "Failed login: "******" Alias: " + pkt.alias + " Reason: " + banned.type.ToString());
                    zone._client.send(plog);
                    return;
                }

                if (banned.type == Logic.Logic_Bans.Ban.BanType.AccountBan)
                {   //They've been blocked from entering any zone, tell them when to come back
                    plog.bSuccess     = false;
                    plog.loginMessage = "Your account has been temporarily suspended until " + banned.expiration.ToString("f", CultureInfo.CreateSpecificCulture("en-US"));

                    Log.write(TLog.Warning, "Failed login: "******" Alias: " + pkt.alias + " Reason: " + banned.type.ToString());
                    zone._client.send(plog);
                    return;
                }

                //They made it!

                //We have the account associated!
                plog.permission = (PlayerPermission)account.permission;
                if (account.permission > (int)PlayerPermission.Sysop)
                {
                    plog.permission = PlayerPermission.Sysop;
                }

                //Attempt to find the related alias
                Data.DB.alias alias = db.alias.SingleOrDefault(a => a.name.Equals(pkt.alias));
                Data.DB.stats stats = null;

                //Is there already a player online under this alias?
                if (alias != null && zone._server._zones.Any(z => z.hasAliasPlayer(alias.id)))
                {
                    plog.bSuccess     = false;
                    plog.loginMessage = "Alias is currently in use.";

                    zone._client.send(plog);
                    return;
                }

                if (alias == null && !pkt.bCreateAlias)
                {       //Prompt him to create a new alias if he has room
                    int maxAliases = 30;
                    if (account.alias.Count < maxAliases)
                    {   //He has space! Prompt him to make a new alias
                        plog.bSuccess  = false;
                        plog.bNewAlias = true;

                        zone._client.send(plog);
                        return;
                    }
                    else
                    {
                        plog.bSuccess     = false;
                        plog.loginMessage = "Your account has reached the maximum number of " + maxAliases.ToString() + " aliases allowed.";

                        zone._client.send(plog);
                        return;
                    }
                }
                else if (alias == null && pkt.bCreateAlias)
                {       //We want to create a new alias!
                    alias = new InfServer.Data.DB.alias();

                    alias.name       = pkt.alias;
                    alias.creation   = DateTime.Now;
                    alias.account1   = account;
                    alias.IPAddress  = pkt.ipaddress;
                    alias.lastAccess = DateTime.Now;
                    alias.timeplayed = 0;

                    db.alias.InsertOnSubmit(alias);

                    Log.write(TLog.Normal, "Creating new alias '{0}' on account '{1}'", pkt.alias, account.name);
                }
                else if (alias != null)
                {       //We can't recreate an existing alias or login to one that isn't ours..
                    if (pkt.bCreateAlias ||
                        alias.account1 != account)
                    {
                        plog.bSuccess     = false;
                        plog.loginMessage = "The specified alias already exists.";

                        zone._client.send(plog);
                        return;
                    }
                }

                //Do we have a player row for this zone?
                player = db.players.SingleOrDefault(
                    plyr => plyr.alias1 == alias && plyr.zone1 == zone._zone);

                if (player == null)
                {       //We need to create another!
                    player = new InfServer.Data.DB.player();

                    player.squad1 = null;
                    player.zone   = zone._zone.id;
                    player.alias1 = alias;

                    player.lastAccess = DateTime.Now;
                    player.permission = 0;

                    //Create a blank stats row
                    stats = new InfServer.Data.DB.stats();

                    stats.zone    = zone._zone.id;
                    player.stats1 = stats;

                    db.stats.InsertOnSubmit(stats);
                    db.players.InsertOnSubmit(player);

                    //It's a first-time login, so no need to load stats
                    plog.bFirstTimeSetup = true;
                }
                else
                {       //Load the player details and stats!
                    plog.banner     = player.banner;
                    plog.permission = (PlayerPermission)Math.Max(player.permission, (int)plog.permission);

                    if (player.permission > account.permission)
                    {
                        //He's a dev here, set the bool
                        plog.developer = true;
                    }

                    //Check for admin
                    Data.DB.alias aliasMatch = null;
                    foreach (string str in Logic_Admins.ServerAdmins)
                    {
                        if ((aliasMatch = db.alias.SingleOrDefault(a => string.Compare(a.name, str, true) == 0)) != null)
                        {
                            if (account.id == aliasMatch.account && account.permission >= 5)
                            {
                                plog.admin = true;
                                break;
                            }
                        }
                    }
                    //If he isn't part of the admin list, he doesn't get powers
                    if (!plog.admin && account.permission >= 5)
                    {
                        account.permission = 0;
                    }

                    plog.squad = (player.squad1 == null) ? "" : player.squad1.name;
                    if (player.squad1 != null)
                    {
                        plog.squadID = player.squad1.id;
                    }

                    stats = player.stats1;

                    plog.stats.zonestat1  = stats.zonestat1;
                    plog.stats.zonestat2  = stats.zonestat2;
                    plog.stats.zonestat3  = stats.zonestat3;
                    plog.stats.zonestat4  = stats.zonestat4;
                    plog.stats.zonestat5  = stats.zonestat5;
                    plog.stats.zonestat6  = stats.zonestat6;
                    plog.stats.zonestat7  = stats.zonestat7;
                    plog.stats.zonestat8  = stats.zonestat8;
                    plog.stats.zonestat9  = stats.zonestat9;
                    plog.stats.zonestat10 = stats.zonestat10;
                    plog.stats.zonestat11 = stats.zonestat11;
                    plog.stats.zonestat12 = stats.zonestat12;

                    plog.stats.kills         = stats.kills;
                    plog.stats.deaths        = stats.deaths;
                    plog.stats.killPoints    = stats.killPoints;
                    plog.stats.deathPoints   = stats.deathPoints;
                    plog.stats.assistPoints  = stats.assistPoints;
                    plog.stats.bonusPoints   = stats.bonusPoints;
                    plog.stats.vehicleKills  = stats.vehicleKills;
                    plog.stats.vehicleDeaths = stats.vehicleDeaths;
                    plog.stats.playSeconds   = stats.playSeconds;

                    plog.stats.cash            = stats.cash;
                    plog.stats.inventory       = new List <PlayerStats.InventoryStat>();
                    plog.stats.experience      = stats.experience;
                    plog.stats.experienceTotal = stats.experienceTotal;
                    plog.stats.skills          = new List <PlayerStats.SkillStat>();

                    //Convert the binary inventory/skill data
                    if (player.inventory != null)
                    {
                        DBHelpers.binToInventory(plog.stats.inventory, player.inventory);
                    }
                    if (player.skills != null)
                    {
                        DBHelpers.binToSkills(plog.stats.skills, player.skills);
                    }
                }

                //Rename him
                plog.alias = alias.name;

                //Try and submit any new rows before we try and use them
                try
                {
                    db.SubmitChanges();
                }
                catch (Exception e)
                {
                    plog.bSuccess     = false;
                    plog.loginMessage = "Unable to create new player / alias, please try again.";
                    Log.write(TLog.Exception, "Exception adding player or alias to DB: {0}", e);
                    zone._client.send(plog);
                    return;
                }

                //Add them
                if (zone.newPlayer(pkt.player.id, alias.name, player))
                {
                    plog.bSuccess = true;
                    Log.write("Player '{0}' logged into zone '{1}'", alias.name, zone._zone.name);

                    //Modify his alias IP address and access times
                    alias.IPAddress  = pkt.ipaddress.Trim();
                    alias.lastAccess = DateTime.Now;

                    //Change it
                    db.SubmitChanges();
                }
                else
                {
                    plog.bSuccess     = false;
                    plog.loginMessage = "Unknown login failure.";
                    Log.write("Failed adding player '{0}' from '{1}'", alias.name, zone._zone.name);
                }

                //Give them an answer
                zone._client.sendReliable(plog);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Handles the login request packet sent by the client
        /// </summary>
        static public void Handle_CS_Login(CS_Login pkt, Client <Player> client)
        {               //Let's escalate our client's status to player!
            ZoneServer server = (client._handler as ZoneServer);

            // check for excessive joins to zone from same IP
            if (pkt.bCreateAlias != true && server._connections.ContainsKey(client._ipe.Address))
            {
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Please wait 10 seconds before logging in again.");
                Log.write(TLog.Warning, "Possible throttler removed: {0}", client._ipe.ToString());
                return;
            }
            else if (!server._connections.ContainsKey(client._ipe.Address))
            {
                server._connections.Add(client._ipe.Address, DateTime.Now.AddSeconds(10));
            }

            //Check their client version and UIDs
            //TODO: find out what the UIDs are and what an invalid UID might look like, and reject spoofed ones
            if (pkt.Version != Helpers._serverVersion ||
                pkt.UID1 <= 10000 ||
                pkt.UID2 <= 10000 ||
                pkt.UID3 <= 10000)
            {
                Log.write(TLog.Warning, "Suspicious login packet from {0} : Version ({1}) UID1({2}) UID2({3}) UID3({4})",
                          pkt.Username,
                          pkt.Version,
                          pkt.UID1,
                          pkt.UID2,
                          pkt.UID3);
            }

            String alias = pkt.Username;

            //Check alias for illegal characters
            if (String.IsNullOrWhiteSpace(alias))
            {
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Alias cannot be blank.");
                return;
            }
            try
            { //Temporary till we find the login bug
                if (!char.IsLetterOrDigit(alias, 0) ||
                    char.IsWhiteSpace(alias, 0) ||
                    char.IsWhiteSpace(alias, alias.Length - 1) ||
                    alias != Logic_Text.RemoveIllegalCharacters(alias))
                {   //Boot him..
                    Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Alias contains illegal characters, must start with a letter or number and cannot end with a space.");
                    return;
                }
            }
            catch (ArgumentOutOfRangeException)
            {
                Log.write(TLog.Warning, "Player login name is {0}", alias);
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Alias contains illegal characters, must start with a letter or number and cannot end with a space.");
                return;
            }

            if (alias.Length > 64)
            {
                //Change this if alias.name in the db is changed.. currently at varchar(64)
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Alias length is too long.");
                return;
            }

            //Are we in permission mode?
            if (server._config["server/permitMode"].boolValue && !Logic_Permit.checkPermit(alias))
            {
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Zone is in permission only mode.");
                return;
            }

            if (server._clients.Values.Count(x => x._ipe.Address.ToString() == client._ipe.Address.ToString()) > 3)
            {
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Too many connections from same IP.");
                Log.write(TLog.Error, "Too many concurrent connections from IP Address {0}", client._ipe.Address);
                return;
            }

            Player newPlayer = server.newPlayer(client, alias);

            //If it failed for some reason, present a failure message
            if (newPlayer == null)
            {
                Helpers.Login_Response(client, SC_Login.Login_Result.Failed, "Login Failure, Zone is full.");
                Log.write(TLog.Error, "New player is null possibly due to zone being full.");
                return;
            }

            newPlayer._UID1 = pkt.UID1;
            newPlayer._UID2 = pkt.UID2;
            newPlayer._UID3 = pkt.UID3;

            //Are we in standalone mode?
            if (server.IsStandalone)
            {                   //Always first time setup in standalone mode
                newPlayer.assignFirstTimeStats(false);

                //Success! Let him in.
                Helpers.Login_Response(client, SC_Login.Login_Result.Success, "This server is currently in stand-alone mode. Your character's scores and stats will not be saved.");
            }
            else
            {                   //Defer the request to the database server
                CS_PlayerLogin <Data.Database> plogin = new CS_PlayerLogin <Data.Database>();

                plogin.bCreateAlias = pkt.bCreateAlias;

                plogin.player    = newPlayer.toInstance();
                plogin.alias     = alias;
                plogin.ticketid  = pkt.TicketID;
                plogin.UID1      = pkt.UID1;
                plogin.UID2      = pkt.UID2;
                plogin.UID3      = pkt.UID3;
                plogin.NICInfo   = pkt.NICInfo;
                plogin.ipaddress = pkt._client._ipe.Address.ToString().Trim();

                server._db.send(plogin);
            }
        }