Exemple #1
0
        /// <summary>
        /// Simple helper method that creates rows to be returned from a SparseRowset-based bound service
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="header"></param>
        /// <returns></returns>
        public PyDataType DataFromMySqlReader(int pkFieldIndex, MySqlDataReader reader, Dictionary <PyDataType, int> rowsIndex)
        {
            PyList result = new PyList();

            while (reader.Read() == true)
            {
                PyDataType keyValue = Utils.ObjectFromColumn(reader, pkFieldIndex);

                result.Add(new PyTuple(new PyDataType[]
                {
                    keyValue, rowsIndex[keyValue], Row.FromMySqlDataReader(reader, this.Headers)
                }
                                       )
                           );
            }

            return(result);
        }
Exemple #2
0
        private void InitializeCharacter()
        {
            // perform basic checks on the skill queue

            // iterate the skill queue and generate a timer for the first skill that must be trained
            // this also prepares the correct notification for multiple skill training done
            PyList <PyInteger> skillTypeIDs           = new PyList <PyInteger>();
            List <Character.SkillQueueEntry> toRemove = new List <Character.SkillQueueEntry>();

            foreach (Character.SkillQueueEntry entry in this.Character.SkillQueue)
            {
                if (entry.Skill.ExpiryTime < DateTime.Now.ToFileTimeUtc())
                {
                    // ensure the skill is marked as trained and that they have the correct values stored
                    entry.Skill.Level      = entry.TargetLevel;
                    entry.Skill.Flag       = Flags.Skill;
                    entry.Skill.ExpiryTime = 0;

                    // add the skill to the list of trained skills for the big notification
                    skillTypeIDs.Add(entry.Skill.Type.ID);
                    toRemove.Add(entry);

                    // update it's location in the client if needed
                    this.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(entry.Skill, Flags.SkillInTraining));
                    // also notify attribute changes
                    this.Client.NotifyAttributeChange(new Attributes[] { Attributes.skillPoints, Attributes.skillLevel }, entry.Skill);
                }
            }

            // remove skills that already expired
            this.Character.SkillQueue.RemoveAll(x => toRemove.Contains(x));

            // send notification of multiple skills being finished training (if any)
            if (skillTypeIDs.Count > 0)
            {
                this.Client.NotifyMultiEvent(new OnGodmaMultipleSkillsTrained(skillTypeIDs));
            }

            // persists the skill queue
            this.Character.Persist();

            // setup the process for training next skill in the queue
            this.SetupTimerForNextSkillInQueue();
        }
Exemple #3
0
        public PyList FetchLiveUpdates()
        {
            try
            {
                MySqlConnection connection = null;
                MySqlDataReader reader     = Database.Query(ref connection,
                                                            "SELECT updateID, updateName, description, machoVersionMin, machoVersionMax, buildNumberMin, buildNumberMax, methodName, objectID, codeType, code, OCTET_LENGTH(code) as codeLength FROM eveLiveUpdates"
                                                            );

                using (connection)
                    using (reader)
                    {
                        PyList result = new PyList();

                        while (reader.Read())
                        {
                            PyDictionary entry = new PyDictionary();
                            PyDictionary code  = new PyDictionary();

                            // read the blob for the liveupdate
                            byte[] buffer = new byte[reader.GetUInt32(11)];
                            reader.GetBytes(10, 0, buffer, 0, buffer.Length);

                            code["code"]       = buffer;
                            code["codeType"]   = reader.GetString(9);
                            code["methodName"] = reader.GetString(7);
                            code["objectID"]   = reader.GetString(8);

                            entry["code"] = new PyObjectData("util.KeyVal", code);

                            result.Add(
                                new PyObjectData("util.KeyVal", entry)
                                );
                        }

                        return(result);
                    }
            }
            catch (Exception)
            {
                Log.Error($"Cannot prepare live-updates information for client");
                throw;
            }
        }
Exemple #4
0
        public PyDataType CharStartTrainingSkillByTypeID(PyInteger typeID, CallInformation call)
        {
            // get the skill the player wants to train
            Skill skill = this.Character.InjectedSkills.First(x => x.Value.Type.ID == typeID).Value;

            // do not start the skill training if the level is 5 already
            if (skill is null || skill.Level == 5)
            {
                return(null);
            }

            PyList <PyTuple> queue = new PyList <PyTuple>(1)
            {
                [0] = new PyTuple(2)
                {
                    [0] = typeID,
                    [1] = skill.Level + 1
                }
            };


            // build a list of skills to train based off the original queue
            // but with the new skill on top
            foreach (Character.SkillQueueEntry entry in this.Character.SkillQueue)
            {
                // ignore the skill in the queue if it was the one requested
                if (entry.Skill.Type.ID == typeID)
                {
                    continue;
                }

                queue.Add(
                    new PyTuple(2)
                {
                    [0] = entry.Skill.Type.ID,
                    [1] = entry.TargetLevel
                }
                    );
            }

            // save the new skill queue
            return(this.SaveSkillQueue(queue, call));
        }
Exemple #5
0
        /// <summary>
        /// Simple helper method that creates a correct util.Rowset ready to be sent
        /// to the EVE Online client based on the given MySqlDataReader
        /// </summary>
        /// <param name="reader"></param>
        /// <returns></returns>
        public static PyDataType FromMySqlDataReader(MySqlDataReader reader)
        {
            // ensure the result is not empty
            if (reader.FieldCount == 0)
            {
                return(new PyObjectData(TYPE_NAME, new PyDictionary()));
            }

            // create the main container for the util.Rowset
            PyDictionary arguments = new PyDictionary();
            // create the header for the rows
            PyList header = new PyList();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                header.Add(reader.GetName(i));
            }

            // store the header and specify the type of rows the Rowset contains
            arguments["header"]   = header;
            arguments["RowClass"] = new PyToken(ROW_TYPE_NAME);

            // finally fill the list of lines the rowset has with the final PyDataTypes
            // based off the column's values
            PyList rowlist = new PyList();

            while (reader.Read() == true)
            {
                PyList linedata = new PyList();

                for (int i = 0; i < reader.FieldCount; i++)
                {
                    linedata.Add(Utils.ObjectFromColumn(reader, i));
                }

                rowlist.Add(linedata);
            }

            arguments["lines"] = rowlist;

            return(new PyObjectData(TYPE_NAME, arguments));
        }
Exemple #6
0
        /// <summary>
        /// Simple helper method that creates rows to be returned from a SparseRowset-based bound service
        /// </summary>
        /// <param name="pkFieldIndex">The field to use as primary key</param>
        /// <param name="reader">The reader to read data from the database</param>
        /// <param name="rowsIndex">The indexed rows</param>
        /// <returns></returns>
        public PyList <PyTuple> DataFromMySqlReader(int pkFieldIndex, MySqlDataReader reader, Dictionary <PyDataType, int> rowsIndex)
        {
            PyList <PyTuple> result = new PyList <PyTuple>();

            while (reader.Read() == true)
            {
                PyDataType keyValue = IDatabaseConnection.ObjectFromColumn(reader, this.FieldTypes[pkFieldIndex], pkFieldIndex);

                result.Add(
                    new PyTuple(3)
                {
                    [0] = keyValue,
                    [1] = rowsIndex[keyValue],
                    [2] = Row.FromMySqlDataReader(reader, this.Headers, this.FieldTypes)
                }
                    );
            }

            return(result);
        }
Exemple #7
0
        /// <summary>
        /// Simple helper method that creates a correct RowList and returns
        /// it's PyDataType representation, ready to be sent to the EVE Online client
        ///
        /// </summary>
        /// <param name="reader">The MySqlDataReader to read the data from</param>
        /// <returns></returns>
        public static PyDataType FromMySqlDataReader(MySqlDataReader reader)
        {
            PyList colums = new PyList(reader.FieldCount);
            PyList lines  = new PyList();

            for (int i = 0; i < reader.FieldCount; i++)
            {
                colums[i] = reader.GetName(i);
            }

            while (reader.Read() == true)
            {
                lines.Add(Row.FromMySqlDataReader(reader, colums));
            }

            return(new PyTuple(2)
            {
                [0] = colums,
                [1] = lines
            });
        }
Exemple #8
0
        /// <summary>
        /// Simple helper method that creates a correct tupleset and returns
        /// it's PyDataType representation, ready to be sent to the EVE Online client
        /// </summary>
        /// <param name="connection">The connection used</param>
        /// <param name="reader">The MySqlDataReader to read the data from</param>
        /// <returns></returns>
        public static PyDataType FromMySqlDataReader(IDatabaseConnection connection, MySqlDataReader reader)
        {
            connection.GetDatabaseHeaders(reader, out PyList <PyString> columns, out FieldType[] fieldTypes);
            PyList rows = new PyList();

            while (reader.Read() == true)
            {
                PyList linedata = new PyList(columns.Count);

                for (int i = 0; i < columns.Count; i++)
                {
                    linedata[i] = IDatabaseConnection.ObjectFromColumn(reader, fieldTypes[i], i);
                }

                rows.Add(linedata);
            }

            return(new PyTuple(2)
            {
                [0] = columns,
                [1] = rows
            });
        }
Exemple #9
0
        public PyList <PyTuple> GetGuests(CallInformation call)
        {
            int stationID = call.Client.EnsureCharacterIsInStation();

            Station          station = this.ItemFactory.GetStaticStation(stationID);
            PyList <PyTuple> result  = new PyList <PyTuple>();

            foreach ((int _, Character character) in station.Guests)
            {
                // TODO: UPDATE WHEN FACTION WARS ARE SUPPORTED
                result.Add(
                    new PyTuple(4)
                {
                    [0] = character.CharacterID,
                    [1] = character.Corporation.ID,
                    [2] = character.Corporation.AllianceID,
                    [3] = 0     // facWarID
                }
                    );
            }

            return(result);
        }
Exemple #10
0
        public PyList <PyTuple> GetMapSolarSystemConnection(int constellationID)
        {
            MySqlConnection connection = null;
            MySqlDataReader reader     = Database.PrepareQuery(ref connection,
                                                               "SELECT fromRegionID, fromConstellationID, fromSolarSystemID, toSolarSystemID, toConstellationID, toRegionID FROM mapSolarSystemJumps WHERE fromConstellationID = @locationID",
                                                               new Dictionary <string, object>()
            {
                { "@locationID", constellationID }
            }
                                                               );

            using (connection)
                using (reader)
                {
                    PyList <PyTuple> result = new PyList <PyTuple>();

                    while (reader.Read() == true)
                    {
                        result.Add(
                            new PyTuple(9)
                        {
                            [0] = "",
                            [1] = reader.GetInt32(0),
                            [2] = reader.GetInt32(1),
                            [3] = reader.GetInt32(2),
                            [4] = 0,
                            [5] = 0,
                            [6] = reader.GetInt32(3),
                            [7] = reader.GetInt32(4),
                            [8] = reader.GetInt32(5),
                        }
                            );
                    }

                    return(result);
                }
        }
Exemple #11
0
        public PyList <PyTuple> GetMapRegionConnection(int universeID)
        {
            MySqlConnection connection = null;
            MySqlDataReader reader     = Database.PrepareQuery(ref connection,
                                                               "SELECT origin.regionID AS fromRegionID, origin.constellationID AS fromConstellationID, origin.solarSystemID AS fromSolarSystemID, stargateID, celestialID, destination.solarSystemID AS toSolarSystemID, destination.constellationID AS toConstellationID, destination.regionID AS toRegionID FROM mapJumps LEFT JOIN mapDenormalize origin ON origin.itemID = mapJumps.stargateID LEFT JOIN mapDenormalize destination ON destination.itemID = mapJumps.celestialID",
                                                               new Dictionary <string, object>()
            {
                { "@locationID", universeID }
            }
                                                               );

            using (connection)
                using (reader)
                {
                    PyList <PyTuple> result = new PyList <PyTuple>();

                    while (reader.Read() == true)
                    {
                        result.Add(
                            new PyTuple(9)
                        {
                            [0] = "",
                            [1] = reader.GetInt32(0),
                            [2] = reader.GetInt32(1),
                            [3] = reader.GetInt32(2),
                            [4] = reader.GetInt32(3),
                            [5] = reader.GetInt32(4),
                            [6] = reader.GetInt32(5),
                            [7] = reader.GetInt32(6),
                            [8] = reader.GetInt32(7),
                        }
                            );
                    }

                    return(result);
                }
        }
Exemple #12
0
        public PyList GetOnlineCharsOnChannel(int channelID)
        {
            MySqlConnection connection = null;
            MySqlDataReader reader     = Database.PrepareQuery(ref connection,
                                                               "SELECT accessor FROM lscChannelPermissions LEFT JOIN chrInformation ON accessor = characterID WHERE channelID = @channelID AND online = 1 AND `mode` > 0",
                                                               new Dictionary <string, object>()
            {
                { "@channelID", channelID }
            }
                                                               );

            using (connection)
                using (reader)
                {
                    PyList result = new PyList();

                    while (reader.Read() == true)
                    {
                        result.Add(reader.GetInt32(0));
                    }

                    return(result);
                }
        }
Exemple #13
0
        public PyList <PyInteger> GetOnlineFriendList(Character character)
        {
            MySqlConnection connection = null;
            MySqlDataReader reader     = Database.PrepareQuery(ref connection,
                                                               "SELECT accessor AS characterID FROM lscChannelPermissions, chrInformation WHERE lscChannelPermissions.channelID = @characterID AND chrInformation.characterID = lscChannelPermissions.accessor and chrInformation.online = 1",
                                                               new Dictionary <string, object>()
            {
                { "@characterID", character.ID }
            }
                                                               );

            using (connection)
                using (reader)
                {
                    PyList <PyInteger> result = new PyList <PyInteger>();

                    while (reader.Read() == true)
                    {
                        result.Add(reader.GetInt32(0));
                    }

                    return(result);
                }
        }
Exemple #14
0
        public PyObjectData GetMarketGroups()
        {
            // this one is a messy boy, there is a util.FilterRowset which is just used here presumably
            // due to this being an exclusive case, better build it manually and call it a day
            Rowset result = Database.PrepareRowsetQuery("SELECT marketGroupID, parentGroupID, marketGroupName, description, graphicID, hasTypes, 0 AS types, 0 AS dataID FROM invMarketGroups ORDER BY parentGroupID");

            // build some dicts to know what points where
            Dictionary <int, List <int> > marketToTypeID = new Dictionary <int, List <int> >();
            // Dictionary<int, int> marketToParent = new Dictionary<int, int>();
            Dictionary <int, List <int> > parentToMarket   = new Dictionary <int, List <int> >();
            Dictionary <int, List <int> > marketTypeIDsMap = new Dictionary <int, List <int> >();

            MySqlConnection connection = null;
            MySqlDataReader reader     = null;

            reader = Database.Query(ref connection, "SELECT marketGroupID, parentGroupID FROM invMarketGroups");

            using (connection)
                using (reader)
                {
                    while (reader.Read() == true)
                    {
                        int child  = reader.GetInt32(0);
                        int parent = reader.IsDBNull(1) == true ? -1 : reader.GetInt32(1);

                        if (parentToMarket.ContainsKey(parent) == false)
                        {
                            parentToMarket[parent] = new List <int>();
                        }

                        parentToMarket[parent].Add(child);
                        // marketToParent[child] = parent;
                    }
                }

            connection = null;

            reader = Database.Query(ref connection, "SELECT marketGroupID, typeID FROM invTypes WHERE marketGroupID IS NOT NULL ORDER BY marketGroupID");

            using (connection)
                using (reader)
                {
                    while (reader.Read() == true)
                    {
                        int marketGroupID = reader.GetInt32(0);
                        int typeID        = reader.GetInt32(1);

                        if (marketToTypeID.ContainsKey(marketGroupID) == false)
                        {
                            marketToTypeID[marketGroupID] = new List <int>();
                        }

                        marketToTypeID[marketGroupID].Add(typeID);
                    }
                }

            // maps for ids are already built, time to build the correct list of item types
            this.BuildItemTypeList(ref marketTypeIDsMap, marketToTypeID, parentToMarket, -1);

            PyDictionary finalResult = new PyDictionary();
            PyNone       key         = new PyNone();

            foreach (PyList row in result.Rows)
            {
                PyInteger  marketGroupID = row[0] as PyInteger;
                PyDataType parentGroupID = row[1];

                PyList <PyInteger> types = new PyList <PyInteger>();

                if (marketTypeIDsMap.TryGetValue(marketGroupID, out List <int> typeIDsMap) == true)
                {
                    foreach (int typeID in typeIDsMap)
                    {
                        types.Add(typeID);
                    }
                }

                row[6] = types;

                PyDataType resultKey = parentGroupID ?? key;

                if (finalResult.TryGetValue(resultKey, out PyList values) == false)
                {
                    finalResult[resultKey] = values = new PyList();
                }

                values.Add(row);
            }

            return(new PyObjectData("util.FilterRowset", new PyDictionary
            {
                ["header"] = result.Header,
                ["idName"] = "parentGroupID",
                ["RowClass"] = new PyToken("util.Row"),
                ["idName2"] = null,
                ["items"] = finalResult
            }
                                    ));
        }
Exemple #15
0
        public PyDataType AddToEndOfSkillQueue(PyInteger typeID, PyInteger level, CallInformation call)
        {
            // the skill queue must start only if it's empty OR there's something already in there
            bool shouldStart = true;

            if (this.Character.SkillQueue.Count > 0)
            {
                shouldStart = this.Character.SkillQueue[0].Skill.ExpiryTime != 0;
            }

            // get the skill the player wants to train
            Skill skill = this.Character.InjectedSkills.First(x => x.Value.Type.ID == typeID).Value;

            // do not start the skill training if the level is 5 already
            if (skill is null || skill.Level == 5)
            {
                return(null);
            }

            PyList <PyTuple> queue = new PyList <PyTuple>();

            bool alreadyAdded = false;

            // build a list of skills to train based off the original queue
            // but with the new skill on top
            foreach (Character.SkillQueueEntry entry in this.Character.SkillQueue)
            {
                // ignore the skill in the queue if it was the one requested
                if (entry.Skill.Type.ID == typeID && entry.TargetLevel == level)
                {
                    alreadyAdded = true;
                }

                queue.Add(
                    new PyTuple(2)
                {
                    [0] = entry.Skill.Type.ID,
                    [1] = entry.TargetLevel
                }
                    );
            }

            if (alreadyAdded == false)
            {
                queue.Add(
                    new PyTuple(2)
                {
                    [0] = typeID,
                    [1] = level
                }
                    );
            }

            // save the new skill queue
            this.SaveSkillQueue(queue, call);

            if (shouldStart == false)
            {
                // stop the queue, there's nothing we should be training as the queue is currently paused
                this.CharStopTrainingSkill(call);
            }

            return(null);
        }
Exemple #16
0
        public PyDataType JoinChannels(PyList channels, PyInteger role, CallInformation call)
        {
            int callerCharacterID = call.Client.EnsureCharacterIsSelected();

            PyList result = new PyList();

            foreach (PyDataType channel in channels)
            {
                int        channelID;
                string     channelType;
                int?       entityID;
                PyDataType channelIDExtended = null;

                try
                {
                    this.ParseChannelIdentifier(channel, out channelID, out channelType, out entityID);
                }
                catch (InvalidDataException)
                {
                    throw new LSCCannotJoin("The specified channel cannot be found: " + PrettyPrinter.FromDataType(channel));
                }

                if (channelType == ChatDB.CHANNEL_TYPE_NORMAL)
                {
                    channelIDExtended = channelID;
                }
                else
                {
                    channelIDExtended = new PyTuple(1)
                    {
                        [0] = new PyTuple(2)
                        {
                            [0] = channelType,
                            [1] = entityID
                        }
                    };
                }

                // send notifications only on channels that should be receiving notifications
                // we don't want people in local to know about players unless they talk there
                if (channelType != ChatDB.CHANNEL_TYPE_REGIONID && channelType != ChatDB.CHANNEL_TYPE_CONSTELLATIONID && channelType != ChatDB.CHANNEL_TYPE_SOLARSYSTEMID2)
                {
                    PyDataType notification =
                        GenerateLSCNotification("JoinChannel", channelIDExtended, new PyTuple(0), call.Client);

                    if (channelType == ChatDB.CHANNEL_TYPE_NORMAL)
                    {
                        if (channelID < ChatDB.MIN_CHANNEL_ENTITY_ID)
                        {
                            // get users in the channel that are online now
                            PyList characters = this.DB.GetOnlineCharsOnChannel(channelID);

                            // notify them all
                            call.Client.ClusterConnection.SendNotification("OnLSC", "charid", characters, notification);
                        }
                    }
                    else
                    {
                        // notify all players on the channel
                        call.Client.ClusterConnection.SendNotification("OnLSC", channelType, new PyDataType [] { entityID }, notification);
                    }
                }

                try
                {
                    result.Add(
                        this.GetChannelInformation(
                            channelType, channelID, entityID, callerCharacterID, channelIDExtended, call
                            )
                        );
                }
                catch (Exception e)
                {
                    // most of the time this indicates a destroyed channel
                    // so build a destroy notification and let the client know this channel
                    // can be removed from it's lists
                    if (channelType == ChatDB.CHANNEL_TYPE_NORMAL && channelID != entityID)
                    {
                        // notify everyone in the channel only when it should
                        PyDataType notification =
                            GenerateLSCNotification("DestroyChannel", channelID, new PyTuple(0), call.Client);

                        // notify all characters in the channel
                        call.Client.ClusterConnection.SendNotification("OnLSC", "charid", callerCharacterID, call.Client, notification);
                    }

                    Log.Error($"LSC could not get channel information. Error: {e.Message}");
                }
            }

            return(result);
        }