//Method to delete character from player's account
        public static void DeleteCharacter(int serverid, Session MySession)
        {
            //Opens new Sql connection using connection parameters
            var connectionString = ConfigurationManager.ConnectionStrings["DevLocal"].ConnectionString;

            //Set connection property from connection string and open connection
            using MySqlConnection con = new MySqlConnection(connectionString);
            con.Open();
            //Creates var to store a MySQlcommand with the query and connection parameters.
            using var cmd   = new MySqlCommand("DeleteCharacter", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddWithValue("cServerID", serverid);

            //Executes a reader on the previous var.
            using MySqlDataReader rdr = cmd.ExecuteReader();

            //Log which character serverid was deleted
            Logger.Info($"Deleted Character with ServerID: {serverid}");

            //Create a new list of characters after deletion
            List <Character> MyCharacterList = new List <Character>();

            MyCharacterList = SQLOperations.AccountCharacters(MySession);

            //Send Fresh Character Listing
            ProcessOpcode.CreateCharacterList(MyCharacterList, MySession);
        }
示例#2
0
        public static void ProcessMessageBundle(Session MySession, List <byte> MyPacket)
        {
            ///Need to consider how many messages could be in here, and message types
            ///FB/FA/40/F9
            ///
            while (MyPacket.Count() > 0)
            {
                ///Get our Message Type
                ushort MessageTypeOpcode = GrabOpcode(MyPacket);
                switch (MessageTypeOpcode)
                {
                //General opcodes (0xFB, 0xF9's)
                case MessageOpcodeTypes.ShortReliableMessage:
                case MessageOpcodeTypes.LongReliableMessage:
                case MessageOpcodeTypes.UnknownMessage:
                    ///Work on processing this opcode
                    ProcessOpcode.ProcessOpcodes(MySession, MessageTypeOpcode, MyPacket);
                    break;

                //Client Actor update (0x4029's)
                case UnreliableTypes.ClientActorUpdate:
                    ProcessUnreliable.ProcessUnreliables(MySession, MessageTypeOpcode, MyPacket);
                    break;


                default:
                    //Shouldn't get here?
                    Console.WriteLine($"Received unknown Message: {MessageTypeOpcode}");

                    //Should we consume the whole message here if it is unknown so we can keep processing?
                    break;
                }
            }
            MySession.RdpReport          = true;
            MySession.ClientFirstConnect = true;

            //Reset ack timer
            MySession.ResetTimer();

            Logger.Info("Done processing messages in packet");
            ///Should we just initiate responses to clients through here for now?
            ///Ultimately we want to have a seperate thread with a server tick,
            ///that may handle initiating sending messages at timed intervals, and initiating data collection such as C9's
        }
示例#3
0
        ///When server creates internal master sessions, key difference is AccountID atm.... Maybe need to be more complicated eventually
        public Session(ushort clientEndpoint, IPEndPoint MyIPEndPoint, int AccountID)
        ///public Session(ushort clientEndpoint, ushort RemoteMaster, ushort SessionPhase, uint SessionIDBase, uint SessionIDUp, uint AccountID)
        {
            Logger.Info("Creating Master Session");
            this.ClientEndpoint = clientEndpoint;
            this.RemoteMaster   = true;
            this.MyIPEndPoint   = MyIPEndPoint;

            ///Need to perform some leg work here to create this internal master session
            this.SessionIDBase = DNP3Creation.DNP3Session();

            ///This will now relate to Our ingame character ID. When we first create our master session, (character ingame ID / 2) - 1 should be our IDUp
            ///Once we start memory dump, IDUp + 1's to be half ingame ID
            this.SessionIDUp = SessionManager.ObtainIDUp() - 1;
            this._AccountID  = AccountID;

            ///We don't need to ack a session this Time, we do however need client to ack our's, should this be tracked?
            this.SessionAck      = true;
            this.CharacterSelect = true;

            ///Trigger contact with client inside session
            ProcessOpcode.GenerateClientContact(this);
            StartTimer(2000);
        }
        //Method to create new character for player's account
        public static void CreateCharacter(Session MySession, Character charCreation)
        {
            //Instantiate new list of Characters to return new character listing


            //Local variables to get string values to store in the DB from dictionary keys received from client
            string humType   = charCreation.HumTypeDict[charCreation.HumTypeNum];
            string classType = charCreation.CharClassDict[charCreation.StartingClass];
            string raceType  = charCreation.CharRaceDict[charCreation.Race];
            string sexType   = charCreation.CharSexDict[charCreation.Gender];

            //Calculate total TP used among all stats for DB storage
            int UsedTP = charCreation.AddStrength + charCreation.AddStamina + charCreation.AddAgility + charCreation.AddDexterity + charCreation.AddWisdom + charCreation.AddIntelligence
                         + charCreation.AddCharisma;

            //Create and Open new Sql connection using connection parameters
            var connectionString = ConfigurationManager.ConnectionStrings["DevLocal"].ConnectionString;

            //Set connection property from connection string and open connection
            using MySqlConnection con = new MySqlConnection(connectionString);
            con.Open();

            //Assign query string and connection to commands
            using var cmd   = new MySqlCommand("GetCharModel", con);
            cmd.CommandType = CommandType.StoredProcedure;

            //Add parameter values for parameterized string.
            cmd.Parameters.AddWithValue("@RaceType", raceType);
            cmd.Parameters.AddWithValue("@ClassType", classType);
            cmd.Parameters.AddWithValue("@HumType", humType);
            cmd.Parameters.AddWithValue("@SexType", sexType);

            //Execute reader on SQL command
            using MySqlDataReader rdr = cmd.ExecuteReader();

            //Iterate through default character values for class and race and assign to new character
            while (rdr.Read())
            {
                charCreation.Tunar               = rdr.GetInt32(5);
                charCreation.UnusedTP            = rdr.GetInt32(7);
                charCreation.TotalAssignableTP   = rdr.GetInt32(8);
                charCreation.XCoord              = rdr.GetFloat(9);
                charCreation.YCoord              = rdr.GetFloat(10);
                charCreation.ZCoord              = rdr.GetFloat(11);
                charCreation.Facing              = rdr.GetFloat(12);
                charCreation.DefaultStrength     = rdr.GetInt32(14);
                charCreation.DefaultStamina      = rdr.GetInt32(15);
                charCreation.DefaultAgility      = rdr.GetInt32(16);
                charCreation.DefaultDexterity    = rdr.GetInt32(17);
                charCreation.DefaultWisdom       = rdr.GetInt32(18);
                charCreation.DefaultIntelligence = rdr.GetInt32(19);
                charCreation.DefaultCharisma     = rdr.GetInt32(20);
                charCreation.ModelID             = rdr.GetInt32(21);
            }
            rdr.Close();
            con.Close();

            //Calculate Unused TP still available to character upon entering world.
            charCreation.UnusedTP = charCreation.UnusedTP - UsedTP;

            //Add total strength from default plus added TP to each category. Not sure this is correct, may need to still add the TP from client
            charCreation.Strength     = charCreation.DefaultStrength + charCreation.AddStrength;
            charCreation.Stamina      = charCreation.DefaultStamina + charCreation.AddStamina;
            charCreation.Agility      = charCreation.DefaultAgility + charCreation.AddAgility;
            charCreation.Dexterity    = charCreation.DefaultDexterity + charCreation.AddDexterity;
            charCreation.Wisdom       = charCreation.DefaultWisdom + charCreation.AddWisdom;
            charCreation.Intelligence = charCreation.DefaultIntelligence + charCreation.AddIntelligence;
            charCreation.Charisma     = charCreation.DefaultCharisma + charCreation.AddCharisma;

            //Open second connection using query string params

            //Set connection property from connection string and open connection
            using MySqlConnection SecondCon = new MySqlConnection(connectionString);
            SecondCon.Open();

            //Create second command using second connection and char insert query string
            using var SecondCmd   = new MySqlCommand("CreateCharacter", SecondCon);
            SecondCmd.CommandType = CommandType.StoredProcedure;

            //Add all character attributes for new character creation to parameterized values
            SecondCmd.Parameters.AddWithValue("@charName", charCreation.CharName);
            //Needs to be MySession.AccountID once CharacterSelect shows characters off true AccountID.
            SecondCmd.Parameters.AddWithValue("AccountID", MySession.AccountID);
            SecondCmd.Parameters.AddWithValue("ModelID", charCreation.ModelID);
            SecondCmd.Parameters.AddWithValue("TClass", charCreation.StartingClass);
            SecondCmd.Parameters.AddWithValue("Race", charCreation.Race);
            SecondCmd.Parameters.AddWithValue("HumType", humType);
            SecondCmd.Parameters.AddWithValue("Level", charCreation.Level);
            SecondCmd.Parameters.AddWithValue("HairColor", charCreation.HairColor);
            SecondCmd.Parameters.AddWithValue("HairLength", charCreation.HairLength);
            SecondCmd.Parameters.AddWithValue("HairStyle", charCreation.HairStyle);
            SecondCmd.Parameters.AddWithValue("FaceOption", charCreation.FaceOption);
            SecondCmd.Parameters.AddWithValue("classIcon", charCreation.StartingClass);
            //May need other default values but these hard set values are placeholders for now
            SecondCmd.Parameters.AddWithValue("TotalXP", 0);
            SecondCmd.Parameters.AddWithValue("Debt", 0);
            SecondCmd.Parameters.AddWithValue("Breath", 255);
            SecondCmd.Parameters.AddWithValue("Tunar", charCreation.Tunar);
            SecondCmd.Parameters.AddWithValue("BankTunar", charCreation.BankTunar);
            SecondCmd.Parameters.AddWithValue("UnusedTP", charCreation.UnusedTP);
            SecondCmd.Parameters.AddWithValue("TotalTP", 350);
            SecondCmd.Parameters.AddWithValue("X", charCreation.XCoord);
            SecondCmd.Parameters.AddWithValue("Y", charCreation.YCoord);
            SecondCmd.Parameters.AddWithValue("Z", charCreation.ZCoord);
            SecondCmd.Parameters.AddWithValue("Facing", charCreation.Facing);
            SecondCmd.Parameters.AddWithValue("Strength", charCreation.Strength);
            SecondCmd.Parameters.AddWithValue("Stamina", charCreation.Stamina);
            SecondCmd.Parameters.AddWithValue("Agility", charCreation.Agility);
            SecondCmd.Parameters.AddWithValue("Dexterity", charCreation.Dexterity);
            SecondCmd.Parameters.AddWithValue("Wisdom", charCreation.Wisdom);
            SecondCmd.Parameters.AddWithValue("Intelligence", charCreation.Intelligence);
            SecondCmd.Parameters.AddWithValue("Charisma", charCreation.Charisma);
            //May need other default or calculated values but these hard set values are placeholders for now
            SecondCmd.Parameters.AddWithValue("CurrentHP", 1000);
            SecondCmd.Parameters.AddWithValue("MaxHP", 1000);
            SecondCmd.Parameters.AddWithValue("CurrentPower", 500);
            SecondCmd.Parameters.AddWithValue("MaxPower", 500);
            SecondCmd.Parameters.AddWithValue("Healot", 20);
            SecondCmd.Parameters.AddWithValue("Powerot", 10);
            SecondCmd.Parameters.AddWithValue("Ac", 0);
            SecondCmd.Parameters.AddWithValue("PoisonR", 10);
            SecondCmd.Parameters.AddWithValue("DiseaseR", 10);
            SecondCmd.Parameters.AddWithValue("FireR", 10);
            SecondCmd.Parameters.AddWithValue("ColdR", 10);
            SecondCmd.Parameters.AddWithValue("LightningR", 10);
            SecondCmd.Parameters.AddWithValue("ArcaneR", 10);
            SecondCmd.Parameters.AddWithValue("Fishing", 0);
            SecondCmd.Parameters.AddWithValue("Base_Strength", charCreation.DefaultStrength);
            SecondCmd.Parameters.AddWithValue("Base_Stamina", charCreation.DefaultStamina);
            SecondCmd.Parameters.AddWithValue("Base_Agility", charCreation.DefaultAgility);
            SecondCmd.Parameters.AddWithValue("Base_Dexterity", charCreation.DefaultDexterity);
            SecondCmd.Parameters.AddWithValue("Base_Wisdom", charCreation.DefaultWisdom);
            SecondCmd.Parameters.AddWithValue("Base_Intelligence", charCreation.DefaultIntelligence);
            SecondCmd.Parameters.AddWithValue("Base_Charisma", charCreation.DefaultCharisma);
            //See above comments regarding hard set values
            SecondCmd.Parameters.AddWithValue("CurrentHP2", 1000);
            SecondCmd.Parameters.AddWithValue("BaseHP", 1000);
            SecondCmd.Parameters.AddWithValue("CurrentPower2", 500);
            SecondCmd.Parameters.AddWithValue("BasePower", 500);
            SecondCmd.Parameters.AddWithValue("Healot2", 20);
            SecondCmd.Parameters.AddWithValue("Powerot2", 10);

            //Execute parameterized statement entering it into the DB
            //using MySqlDataReader SecondRdr = SecondCmd.ExecuteReader();
            SecondCmd.ExecuteNonQuery();
            SecondCon.Close();

            ///Close DB connection
            SecondCon.Close();

            //Log which character serverid was created
            Console.WriteLine($"Created Character with Name: {charCreation.CharName}");

            List <Character> MyCharacterList = new List <Character>();

            MyCharacterList = SQLOperations.AccountCharacters(MySession);

            //Send Fresh Character Listing
            ProcessOpcode.CreateCharacterList(MyCharacterList, MySession);
        }
示例#5
0
        private static void ProcessRdpReport(Session MySession, List <byte> MyPacket, bool UnreliableReport)
        {
            //Eventually incorporate UnreliableReport to cycle through unreliables and update accordingly

            //Read client bundle here. Accept client bundle as is because packets could be lost or dropped, client bundle# should not be "tracked"
            //considerations could be to track it for possible drop/lost rates
            MySession.clientBundleNumber = (ushort)(MyPacket[1] << 8 | MyPacket[0]);
            ushort LastRecvBundleNumber  = (ushort)(MyPacket[3] << 8 | MyPacket[2]);
            ushort LastRecvMessageNumber = (ushort)(MyPacket[5] << 8 | MyPacket[4]);

            //Check our list  of reliable messages to remove
            for (int i = 0; i < MySession.MyMessageList.Count(); i++)
            {
                //If our message stored is less then client ack, need to remove it!
                if (MySession.MyMessageList[i - i].ThisMessagenumber <= LastRecvMessageNumber)
                {
                    MySession.MyMessageList.RemoveAt(0);
                }

                //Need to keep remaining messages, move on
                else
                {
                    break;
                }
            }


            MyPacket.RemoveRange(0, 6);
            ///Only one that really matters, should tie into our packet resender stuff
            if (MySession.serverMessageNumber >= LastRecvMessageNumber)
            {
                ///This should be removing messages from resend mechanics.
                ///Update our last known message ack'd by client
                MySession.clientRecvMessageNumber = LastRecvMessageNumber;
            }

            ///Triggers creating master session
            if (((MySession.clientEndpoint + 1) == (MySession.sessionIDBase & 0x0000FFFF)) && MySession.SessionAck && MySession.serverSelect == false)
            {
                ///Key point here for character select is (MySession.clientEndpoint + 1 == MySession.sessionIDBase)
                ///SessionIDBase is 1 more then clientEndPoint
                ///Assume it's Create Master session?
                Session NewMasterSession = new Session(MySession.clientEndpoint, MySession.MyIPEndPoint, MySession.AccountID);

                SessionManager.AddMasterSession(NewMasterSession);
            }

            ///Trigger Server Select with this?
            else if ((MySession.clientEndpoint == (MySession.sessionIDBase & 0x0000FFFF)) && MySession.SessionAck && MySession.serverSelect == false)
            {
                MySession.serverSelect = true;
            }

            ///Triggers Character select
            else if (MySession.CharacterSelect && (MySession.clientEndpoint != MySession.sessionIDBase))
            {
                MySession.CharacterSelect = false;
                List <Character> MyCharacterList = new List <Character>();
                Logger.Info("Generating Character Select");
                MyCharacterList = SQLOperations.AccountCharacters(MySession);

                //Assign to our session
                MySession.CharacterData = MyCharacterList;

                ProcessOpcode.CreateCharacterList(MyCharacterList, MySession);
            }

            else if (MySession.Dumpstarted)
            {
                //Let client know more data is coming
                if (MySession.MyDumpData.Count() > 500)
                {
                    List <byte> ThisChunk = MySession.MyDumpData.GetRange(0, 500);
                    MySession.MyDumpData.RemoveRange(0, 500);

                    ///Handles packing message into outgoing packet
                    RdpCommOut.PackMessage(MySession, ThisChunk, MessageOpcodeTypes.MultiShortReliableMessage);
                }

                //End of dump
                else
                {
                    List <byte> ThisChunk = MySession.MyDumpData.GetRange(0, MySession.MyDumpData.Count());
                    MySession.MyDumpData.Clear();
                    ///Handles packing message into outgoing packet
                    RdpCommOut.PackMessage(MySession, ThisChunk, MessageOpcodeTypes.ShortReliableMessage);
                    //turn dump off
                    MySession.Dumpstarted = false;

                    //Gather remaining data to send in dump
                    //ignore list
                    ProcessOpcode.IgnoreList(MySession);
                    //Randommessage
                    //RandomFriend
                    //characterSpeed
                    ProcessOpcode.ActorSpeed(MySession);
                    //Some opcode
                }
            }

            else
            {
                Logger.Err($"Client received server message {LastRecvMessageNumber}, expected {MySession.serverMessageNumber}");
            }
        }