X-AntiMutant Updatable habbo figure filter

Results 1 to 17 of 17
  1. #1
    Apprentice masacre10 is offline
    MemberRank
    Sep 2011 Join Date
    20Posts

    X-AntiMutant Updatable habbo figure filter

    Recently some people have come to my hotel and decided that they put some clothes on that are not available, like snowstorm suit and some other stuff. This causes people to become invisible.

    This simple script parses the figuredata XML file and verifies if the part in the figure is on the figuredata.
    I'm sure there are some things that can be improved to the code.


    Create a new class in HabboHotel/Misc/XAntiMutant.cs

    Spoiler:
    Code:
    using System.Collections.Generic;
    using System.Linq;
    using System.Xml.Linq;
    
    namespace Butterfly.HabboHotel.Misc
    {
        class XAntiMutant
        {
            private Dictionary<string, Dictionary<string, Figure>> Parts;
            public XAntiMutant()
            {
                Parts = new Dictionary<string, Dictionary<string, Figure>>();
                ParseLookXMLFile();
            }
    
            void ParseLookXMLFile()
            {
                XDocument Doc = XDocument.Load("http://images.xukys-hotel.com/gamedata/figuredata.nc.1.xml");
                var data = from item in Doc.Descendants("sets")
                           from tItem in Doc.Descendants("settype")
                           select new
                           {
                               Part = tItem.Elements("set"),
                               Type = tItem.Attribute("type"),
                           };
                foreach (var item in data)
                {
                    foreach (var part in item.Part)
                    {
                        string PartName = item.Type.Value;
                        if (!Parts.ContainsKey(PartName))
                            Parts.Add(PartName, new Dictionary<string, Figure>());
    
                        Figure toAddFigure = new Figure(PartName, part.Attribute("id").Value, part.Attribute("gender").Value,
                            part.Attribute("colorable").Value);
    
                        if (!Parts[PartName].ContainsKey(part.Attribute("id").Value))
                            Parts[PartName].Add(part.Attribute("id").Value, toAddFigure);
                    }
                }
            }
    
            internal string RunLook(string Look)
            {
                List<string> toReturnFigureParts = new List<string>();
                List<string> fParts = new List<string>();
                string[] requiredParts = { "hd", "ch" };
                bool flagForDefault = false;
    
                string[] FigureParts = Look.Split('.');
                string genderLook = GetLookGender(Look);
                foreach (string Part in FigureParts)
                {
                    string newPart = Part;
                    string[] tPart = Part.Split('-');
                    if (tPart.Count() < 2)
                    {
                        flagForDefault = true;
                        continue;
                    }
                    string partName = tPart[0];
                    string partId = tPart[1];
    
                    if (!Parts.ContainsKey(partName) || !Parts[partName].ContainsKey(partId) ||
                        (genderLook != "U" && Parts[partName][partId].Gender != "U" &&
                         Parts[partName][partId].Gender != genderLook))
                        newPart = SetDefault(partName, genderLook);
    
                    if (!fParts.Contains(partName)) fParts.Add(partName);
                    if(!toReturnFigureParts.Contains(newPart)) toReturnFigureParts.Add(newPart);
                }
    
                if (flagForDefault)
                {
                    toReturnFigureParts.Clear();
                    toReturnFigureParts.AddRange("hr-115-42.hd-190-1.ch-215-62.lg-285-91.sh-290-62".Split('.'));
                }
    
                foreach (string requiredPart in requiredParts.Where(requiredPart => !fParts.Contains(requiredPart) &&
                                                                                    !toReturnFigureParts.Contains(SetDefault(requiredPart, genderLook))))
                {
                    toReturnFigureParts.Add(SetDefault(requiredPart, genderLook));
                }
    
                return string.Join(".", toReturnFigureParts);
            }
    
            private string GetLookGender(string Look)
            {
                string[] FigureParts = Look.Split('.');
    
                foreach (string Part in FigureParts)
                {
                    string[] tPart = Part.Split('-');
                    if (tPart.Count() < 2) continue;
                    string partName = tPart[0];
                    string partId = tPart[1];
                    if (partName != "hd")
                        continue;
    
                    return Parts.ContainsKey(partName) && Parts[partName].ContainsKey(partId)
                        ? Parts[partName][partId].Gender
                        : "U";
                }
                return "U";
            }
    
            private string SetDefault(string partName, string Gender)
            {
                string partId = "0";
                if (Parts.ContainsKey(partName))
                {
                    KeyValuePair<string, Figure> part = Parts[partName].FirstOrDefault(x => x.Value.Gender == Gender || Gender == "U");
                    partId = part.Equals(default(KeyValuePair<string, Figure>)) ? "0" : part.Key;
                }
                return partName + "-" + partId + "-0";
            }
        }
    
        class Figure
        {
            internal string Part;
            internal string PartId;
            internal string Gender;
            internal string Colorable;
    
            public Figure(string part, string partId, string gender, string colorable)
            {
                Part = part;
                PartId = partId;
                Gender = gender;
                Colorable = colorable;
            }
    
    
        }
    }


    Add the folowing line to this files:

    ButterflyEnvironment.cs
    Spoiler:

    Look for:
    Code:
    internal static string FilterFigure(string figure)
    And change the contents to
    Code:
    return ButterflyEnvironment.GetGame().XAntiMutant().RunLook(figure);


    Messages/Requests/Users.cs
    Spoiler:

    Look for:
    Code:
    internal void ChangeLook()
    Look for the declaration of the variable "look" and below of it put:

    Code:
    look = ButterflyEnvironment.GetGame().XAntiMutant().RunLook(look);


    At HabboHotel/Game.cs

    Spoiler:

    Look for:
    Code:
    internal QuestManager GetQuestManager()
    Below this method, add this one:

    Code:
    internal XAntiMutant XAntiMutant()
            {
                return xAntiMutant;
            }
    Look for:
    Code:
    private QuestManager questManager;
    Below this add:

    Code:
    private XAntiMutant xAntiMutant;

    Look for:
    Code:
    GroupManager = new Group.GroupManager();
    Below this add:
    Code:
    xAntiMutant = new XAntiMutant();



    This post was approved by
    Last edited by masacre10; 25-03-14 at 05:02 AM.


  2. #2
    Member Kodamas is offline
    MemberRank
    Feb 2014 Join Date
    55Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Thank you for sharing :)

  3. #3
    Alpha Member Emily is offline
    MemberRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,408Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Aww noes...

    I thought somebody said a long time using LINQ in a retro server isn't good and slows down (which it actually does).
    But well good program, still I don't like the whole fact of LINQ..

  4. #4
    Valued Member iTzScronnie is offline
    MemberRank
    Sep 2013 Join Date
    104Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Can this be used for Plus (Silverwave)?

  5. #5
    Retired maritnmine is offline
    MemberRank
    May 2007 Join Date
    North KoreaLocation
    1,103Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by Tha View Post
    Aww noes...

    I thought somebody said a long time using LINQ in a retro server isn't good and slows down (which it actually does).
    But well good program, still I don't like the whole fact of LINQ..
    Not really. A long time ago I threw out everything with MySQL in bfly and replaced it with MSSQL and LINQ. It was far faster than MySQL.

  6. #6
    Alpha Member Emily is offline
    MemberRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,408Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by maritnmine View Post
    Not really. A long time ago I threw out everything with MySQL in bfly and replaced it with MSSQL and LINQ. It was far faster than MySQL.
    But I mean this is not used as MySQL replacing. This code has nothing to do with MySQL.

  7. #7
    Retired maritnmine is offline
    MemberRank
    May 2007 Join Date
    North KoreaLocation
    1,103Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by Tha View Post
    But I mean this is not used as MySQL replacing. This code has nothing to do with MySQL.
    LINQ doesn't exactly make your server slower. In many cases, it would be equivalent to a normal foreach loop. My point is that when used incorrectly or over-used, LINQ can harm the performance of your server.

  8. #8
    ~|=_=|~ Receiver is offline
    MemberRank
    Sep 2013 Join Date
    PlutoLocation
    624Posts

    Re: X-AntiMutant Updatable habbo figure filter

    This was very useful thanks for sharing. Does this script work on Plus as well?

  9. #9
    is it me or is it just .. duckietm is offline
    MemberRank
    Oct 2010 Join Date
    339Posts

    Re: X-AntiMutant Updatable habbo figure filter

    yes this works in plus emu after some minor changes !

  10. #10
    Freak Mextur is offline
    MemberRank
    Mar 2012 Join Date
    216Posts

    Re: X-AntiMutant Updatable habbo figure filter

    I think this is a very heavy code. I know it can be shorter. Very nice you use the figuredata!!

  11. #11
    Freak Mextur is offline
    MemberRank
    Mar 2012 Join Date
    216Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by maritnmine View Post
    LINQ doesn't exactly make your server slower. In many cases, it would be equivalent to a normal foreach loop. My point is that when used incorrectly or over-used, LINQ can harm the performance of your server.
    Just use linq for advanced expressions.

  12. #12
    Freak Mextur is offline
    MemberRank
    Mar 2012 Join Date
    216Posts

    Re: X-AntiMutant Updatable habbo figure filter

    LINQ is faster for huge collections. In fact there is also PLINQ. Its better at some scenarios.

    Don't try to code perfect. Code less wrong. That's why they use LINQ because it's readable and quite easy.

  13. #13
    Alpha Member Emily is offline
    MemberRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,408Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by maritnmine View Post
    LINQ doesn't exactly make your server slower. In many cases, it would be equivalent to a normal foreach loop. My point is that when used incorrectly or over-used, LINQ can harm the performance of your server.
    Oh well now get it. I always thought LINQ was slower than for example the foreach keyword itself, but for performance it doesn't matter

  14. #14
    Member Habbo2 is offline
    MemberRank
    Aug 2013 Join Date
    86Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Used a similar system to generate random figures.
    Looking very good at the moment, obvioulsy some room for improvement such as if the Figure set has selectable="1"

  15. #15
    Freak Mextur is offline
    MemberRank
    Mar 2012 Join Date
    216Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Internal keyword doesn't make sens if you don't use these classes as library or whatever. Internal means: public in current Assembly, hidden for Another Assembly.

    Just use public or private, only use internal in case you're dealing with different assemblies.

  16. #16
    Apprentice masacre10 is offline
    MemberRank
    Sep 2011 Join Date
    20Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by Mextur View Post
    I think this is a very heavy code. I know it can be shorter. Very nice you use the figuredata!!
    How did you base the statement that it's a "very heavy code"?

    Quote Originally Posted by Habbo2 View Post
    Used a similar system to generate random figures.
    Looking very good at the moment, obvioulsy some room for improvement such as if the Figure set has selectable="1"
    I didn't see the need of adding it, that didn't cause the invisible thing. But I guess it can be easily added.

  17. #17
    Retired maritnmine is offline
    MemberRank
    May 2007 Join Date
    North KoreaLocation
    1,103Posts

    Re: X-AntiMutant Updatable habbo figure filter

    Quote Originally Posted by Mextur View Post
    Just use linq for advanced expressions.
    Yeah, that will eat up your system resources.


    Quote Originally Posted by Mextur View Post
    Internal keyword doesn't make sens if you don't use these classes as library or whatever. Internal means: public in current Assembly, hidden for Another Assembly.

    Just use public or private, only use internal in case you're dealing with different assemblies.
    Then why use private, why can't we just all use public so everyone can just use everything? Internal is there for a good reason.
    Private: Data members in your class
    Protected: Classes who inherit your class can access these functions/members
    Internal: The classes functions and members that shall be accesses outside the class as long as you are inside your namespace
    Public: Everyone can access this

    Inb4 hurrdurr lets go with public because it "has everything"


    Quote Originally Posted by Mextur View Post
    LINQ is faster for huge collections. In fact there is also PLINQ. Its better at some scenarios.

    Don't try to code perfect. Code less wrong. That's why they use LINQ because it's readable and quite easy.
    You are making an argument against yourself. At the same time you want to write code "that is less wrong". What is the correct code of an abstract code which uses many times as much resources for a simple sort vs a small and simple implementation of insertion sort? Example: Butterfly navigator. When I was profiling it many years ago I noticed a performance spike in the navigator code. It turned out the LINQ code for sorting the navigator cause a huge amount of data to be allocated then thrown away right after. This was because of the way LINQ rhaped my memory. It basically cloned my active rooms collection several times before it got it sorted and ready for use.
    There is no "perfect" code. Each implementation has its pros and cons, there is no ultimate goal. What you want is code that runs fast and is maintainable. Sometimes adding layer after layer of abstraction on top of the code to make it easier for others to read and use hurts performance, and in some cases extremely when over-used.
    Sure, LINQ is easy to use, and it is easy to read. Small simple LINQ statements doesn't hurt your performance. When they start to get large and complex, they may begin to hurt your performance. A lot. Therefore, profiling is important and knowing what happens behind the scenes. (Read my post on how to write a good emulator here) Don't believe me? Look at how faster an optimized algorithm is compared to a huge cluster fuck of LINQ. It may be a bit more code, but it can even be more readable than the LINQ cluster fuck if done right.
    And no, LINQ isn't in any cases faster for huge collections. If you have a huge collection, a "normal" loop through the collection is, hands down, the fastest way as you don't have the overhead of abstraction you have in LINQ which becomes extreme for huge collections.



Advertisement