[C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

Page 3 of 4 FirstFirst 1234 LastLast
Results 31 to 45 of 51
  1. #31
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]
    Attempted to do some points:

    - Console commands are now registered in the ServiceCollection and injected through DI
    - Removed DependencyRegistrar

    https://github.com/Gabriellexo97/Pro...4741bc03663c31

    (Keep in mind I still have to change the .Any I forgot oops)

    PHP Code:
    public class ConsoleCommandHandler
        
    {
            private 
    readonly ILogger<ConsoleCommandHandlerlogger;
            private 
    readonly Dictionary<stringICommandcommands;

            public 
    ConsoleCommandHandler(ILogger<ConsoleCommandHandlerloggerIEnumerable<ICommandcommands)
            {
                
    this.logger logger;
                
    this.commands commands.ToDictionary(command => command.Command);
            }

            public 
    async Task TryHandleCommandAsync(string input)
            {
                
    int spacePosition input.IndexOf(' ');
                
    string header spacePosition >= input.Substring(0spacePosition) : input;

                if (
    commands.Any(command => command.Key == header))
                {
                    
    await commands[header].RunAsync(input.Substring(spacePosition 1).Split(' '));
                }
                else
                {
                    
    logger.LogWarning("'{0}' is not recognized as an internal command"header);
                }
            }
        } 
    PHP Code:
    IServiceCollection serviceDescriptors = new ServiceCollection();
                
    serviceDescriptors.AddLogging(builder => builder.AddConsole());
                
    serviceDescriptors.AddSingleton<MessageHandler>();
                
    serviceDescriptors.AddSingleton<GameNetworkListener>();
                
    serviceDescriptors.AddSingleton<ConsoleCommandHandler>();

                
    serviceDescriptors.AddService<SessionService>();
                
    serviceDescriptors.AddService<HabboService>();

                
    serviceDescriptors.RegisterConsoleCommands(); 
    (view the git repo for all the changed code).

    ----

    Can a MOD change the title of the topic to:

    [C#/.NET Core/R63 Post-shuffle] Project Nordlys

    (how I wish I could do this myself...)
    Last edited by Emily; 01-02-20 at 07:31 PM.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  2. #32
    Evil Scottish Overlord Joopie is offline
    LegendRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,772Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Few minor points:
    - Console methods are always synchronized between threads. Run the method as normal and return Task.Completed instead.
    - GetService returns null when the service can't be found, GetRequiredService on the other hand throws an exception. Makes life easier while debugging to see if you haven't registered it.
    - You could've used the Activator class to create an instance of the service, OR by adding the constructor constraint on your generic parameter (where T : new()).


    Join Our RaGEZONE Discord Now!


    Send me a PM | send me a mail

    Still waiting for XenForo to hit RaGEZONE.

  3. #33
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Joopie View Post
    Few minor points:
    - Console methods are always synchronized between threads. Run the method as normal and return Task.Completed instead.
    - GetService returns null when the service can't be found, GetRequiredService on the other hand throws an exception. Makes life easier while debugging to see if you haven't registered it.
    - You could've used the Activator class to create an instance of the service, OR by adding the constructor constraint on your generic parameter (where T : new()).
    Thanks for the criticism points. About your last point, I assume it'd be like this:

    PHP Code:
    public static void AddService<T>(this IServiceCollection serviceDescriptorswhere T IService, new()
            {
                new 
    T().Register(serviceDescriptors);
            } 
    I assume it wouldn't matter in this case whether to use that or the Activator class? I honestly never thought about these methods (I think I've seen them both before but I never actually used them).

    --

    Going back on a point you made earlier, I wouldn't mind giving EF a go. My only question / concern is, how many DbContext I should use? I've googled a bit and some say one and some say multiple. When using EF I would use code-first so people don't have to import an SQL for it to work. IIRC I remember reading something about that needing to have only one DbContext but not sure.
    Last edited by Emily; 02-02-20 at 09:47 AM.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  4. #34
    Evil Scottish Overlord Joopie is offline
    LegendRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,772Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Emily View Post
    Thanks for the criticism points. About your last point, I assume it'd be like this:

    PHP Code:
    public static void AddService<T>(this IServiceCollection serviceDescriptorswhere T IService, new()
            {
                new 
    T().Register(serviceDescriptors);
            } 
    I assume it wouldn't matter in this case whether to use that or the Activator class? I honestly never thought about these methods (I think I've seen them both before but I never actually used them).

    --

    Going back on a point you made earlier, I wouldn't mind giving EF a go. My only question / concern is, how many DbContext I should use? I've googled a bit and some say one and some say multiple. When using EF I would use code-first so people don't have to import an SQL for it to work. IIRC I remember reading something about that needing to have only one DbContext but not sure.
    A DbContext says something about a group of models that belongs together. I suggest you don't use one DbContext for your entire server, but multiple doing their own thing. You can create as many instances as you like, but don't reuse them. The're designed to be short-lived. When using Asp.NET and are adding a context, it's added as a scope to the service collection. This means one DbContext instance for each request (so you get the idea of the lifetime).
    Nice to see you use code-first migrations, makes live easier migrating new database scheme changes. Keep in mind how you handle existing data!

    There is no difference between the new() constraint and the Activator class. Under the hood, generics having the new() constraint use the Activator class to create an new instance.


    Join Our RaGEZONE Discord Now!


    Send me a PM | send me a mail

    Still waiting for XenForo to hit RaGEZONE.

  5. #35
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Joopie View Post
    A DbContext says something about a group of models that belongs together. I suggest you don't use one DbContext for your entire server, but multiple doing their own thing. You can create as many instances as you like, but don't reuse them. The're designed to be short-lived. When using Asp.NET and are adding a context, it's added as a scope to the service collection. This means one DbContext instance for each request (so you get the idea of the lifetime).
    Nice to see you use code-first migrations, makes live easier migrating new database scheme changes. Keep in mind how you handle existing data!

    There is no difference between the new() constraint and the Activator class. Under the hood, generics having the new() constraint use the Activator class to create an new instance.
    I'll give EF a go then as it's surely a lot better (and easier...) than the way I'm doing it now (and I've worked with EF before so it's not completely new to me). I assume the DbContext would be added as scoped to the DI container and resolved in my controller functions (like GetHabboById, GetHabboByName, Authenticate, etc etc.)
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  6. #36
    Evil Scottish Overlord Joopie is offline
    LegendRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,772Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Keep in mind that adding a DbContext as scoped requires you to create the scope yourself. Without creating a scope you basicly and up with a singleton, which you do not want. Also becareful with using singletons with scoped dependencies.


    Join Our RaGEZONE Discord Now!


    Send me a PM | send me a mail

    Still waiting for XenForo to hit RaGEZONE.

  7. #37
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Joopie View Post
    Keep in mind that adding a DbContext as scoped requires you to create the scope yourself. Without creating a scope you basicly and up with a singleton, which you do not want. Also becareful with using singletons with scoped dependencies.
    I assume I have to add it as scoped and then resolve it in a CreateScope using block?
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  8. #38
    Evil Scottish Overlord Joopie is offline
    LegendRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,772Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Yes, that's correct. The scope determines the lifetime of the scoped dependencies. Also do not use the resolved dependencies outside the using statement. The DI will automatically dispose all objects with the IDisposable interface. It's also a nice way to clean up your shit ;). I also wouldn't recommend creating a new scope everytime you need a context. I once did it for the lifetime of a single connection, but it caused issues with the context being reused too many times and such. I think it would be better to create a scope based on the lifetime of a single message handler. However, it's just a thought I had e and you should test out what works best for you etc.


    Join Our RaGEZONE Discord Now!


    Send me a PM | send me a mail

    Still waiting for XenForo to hit RaGEZONE.

  9. #39
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Started working on integrating entity framework. The code isn't on git yet but basically this means easier communication with the database, as well as no need to import an SQL file and create a database when you start the server.

    The following code is used to add a DbContext:

    PHP Code:
    serviceDescriptors.AddDbContext<HabboDbContext>(); 
    Then on the startup, this code is used to create the database (if needed) and execute all migrations:

    PHP Code:
    await serviceProvider.GetRequiredService<HabboDbContext>().Database.MigrateAsync(); 
    For now, the DbContext will be injected in controllers, like the following:

    PHP Code:
        public class HabboController
        
    {
            private 
    readonly HabboDbContext dbContext;

            public 
    HabboController(HabboDbContext dbContext)
            {
                
    this.dbContext dbContext;
            }

            public 
    Habbo GetHabbo(int id)
            {
                return 
    dbContext.Find<Habbo>(id);
            }

            public 
    Habbo Authenticate(string sso)
            {
                return 
    dbContext.Habbos.Where(habbo => habbo.AuthenticationTicket == sso).FirstOrDefault();
            }
        } 
    There's still room for improvement I'd guess but it's a start now. Of course these controllers will be injected in any part it's necessary, for example the HabboController will be injected in the message event for SSO ticket so the Authenticate method can be called.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  10. #40
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    It has been a while. I could go on with a lot of excuses, but why bother. This is going to be a long post so bear with me.

    This project was started as a little time-filler for when I would be bored, I had something to work on. I had motivation for the project - and I still have - but I can feel developing this feels different. Back in the day (when I was a noob), even if what I did was terrible, it gave me a bit of satisfaction, the satisfaction I lack nowadays. Maybe this is my own fault of trying a million projects (gonna mention it myself before somebody else does), or maybe it's because I've grown out of it, or because the section is dying. Whatever it is, it definitely affects me. Seeing how Cortex is doing, it makes me wonder if there's still a need for a development. If Cortex gets finishes, then what's left to do besides HTML5 development? (yeah, I could work on something HTML5 but that's far outside my league and client development doesn't interest me that much). Obviously, Habbo will launch a new client later this year - which honestly I wonder if we'll ever be able to create a retro from it - but that takes some time. Also, even when it comes out, who knows how long it'll take before real pro's figure out a way to create a retro from it. I definitely have plans to look into it, but again, I'm not a big pro.

    I honestly am stuck. Partly I want to develop something, something I can be proud of (sorta...), but I'm not sure if it's the right time for it (if ever). I don't know whether to continue for the sole reason I can leave something I'm proud of, or not continue because it barely makes sense. The development was started as a sole R38 development for both Shockwave and Flash, but it brought v7 when I got the Lingo scripts for it. Shockwave already was EOL, and now Flash will reach EOL this year as well. I wonder, does it even make sense developing something for that? I know Quackster created Kepler even though Shockwave is EOL a few years already, but still. The sole reason I'd continue the development is to leave something I can be sort of proud of and release the first public-usable stable server that works for R38 both Shockwave and Flash and the first full v7 server ever publicly released. But is it worth the time?

    I did write my "framework", and I can say I'm proud of how that turned out. I did do some client code for v7 (cause I was bored) and a minor amount for R38. Not much to say I would've wasted a lot of time, but enough to maybe consider going on. I'll definitely try posting updates here, but I can't promise anything 100%.

    Now, a few things to mention about my code so far (the code I might or might not put on git depending on whether I'm lazy or not):

    - Using .NET Core for multi platform
    - Using dependency injection
    - Using Entity Framework Core with migrations for easy usage
    - Using the powerful PBKDF2 for hashing passwords
    - Using DotNetty for easy networking
    - Using C# 8.0

    A few snippets of new code:

    PHP Code:
    public class PasswordHash
        
    {
            private const 
    int SaltSize 24// size in bytes
            
    private const int HashSize 24// size in bytes
            
    private const int Iterations 100000// number of pbkdf2 iterations
            
            
    public static byte[] GenerateSalt()
            {
                
    using var provider = new RNGCryptoServiceProvider();
                
    byte[] salt = new byte[SaltSize];
                
    provider.GetBytes(salt);
                return 
    salt;
            }

            public static 
    byte[] Hash(string inputbyte[] salt)
            {
                
    using Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(inputsaltIterations);
                return 
    pbkdf2.GetBytes(HashSize);
            }

            public static 
    bool Verify(string passwordPlayer player)
            {
                
    // This looks ugly... gotta look at this a bit more later but cba now
                
    return Convert.ToBase64String(Hash(passwordConvert.FromBase64String(player.Salt))).Equals(player.Password);
            }
        } 
    PHP Code:
    public class HabboDbContext DbContext
        
    {
            public 
    HabboDbContext()
                : 
    base ()
            {
                
            }

            protected 
    override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
            {
                
    optionsBuilder.UseMySql("Server=127.0.0.1;Database=stargazer_db;Uid=root;Pwd=ThisDatabaseIsNowCompromised;");
            }

            protected 
    override void OnModelCreating(ModelBuilder modelBuilder)
            {
                
    modelBuilder.Entity<Player>().Property(=> p.Motto).HasDefaultValue(string.Empty);
                
    modelBuilder.Entity<Player>().Property(=> p.ConsoleMotto).HasDefaultValue(string.Empty);
                
    modelBuilder.Entity<Player>().Property(=> p.Coins).HasDefaultValue(100);
                
                
    modelBuilder.Entity<PlayerRole>().HasKey(pr => new {pr.PlayerIdpr.RoleId});

                
    modelBuilder.Entity<PlayerRole>()
                    .
    HasOne(pr => pr.Player)
                    .
    WithMany(=> p.Roles)
                    .
    HasForeignKey(pr => pr.PlayerId);

                
    modelBuilder.Entity<PlayerRole>()
                    .
    HasOne(pr => pr.Role)
                    .
    WithMany(=> r.Players)
                    .
    HasForeignKey(pr => pr.RoleId);

                
    modelBuilder.Entity<Role>().HasData(
                    new 
    Role() { Id 1Name "User"},
                    new 
    Role() { Id 2Name "HabboX"},
                    new 
    Role() { Id 3Name "Silver Hobba"},
                    new 
    Role() { Id 4Name "Gold Hobba"},
                    new 
    Role() { Id 5Name "Moderator"},
                    new 
    Role() { Id 6Name "Management"});
            }

            public 
    DbSet<PlayerPlayers getset; }
            public 
    DbSet<RoleRoles getset; }
        } 
    Also, since I haven't done this in a while I definitely want to thank a few people:

    - Quackster: His archive website, shockwave installation stuff, helping with Lingo scripts and stuff (probably more I can't remember)
    - Nillus: For some packet stuff from Blunk/Ion
    - Everybody else: For being here

    I don't ever regret being here or that I ever checked on here, it definitely helped me grow as both a person and a developer and I thank everyone for that.

    If you're still reading, let me know what to do, continue with what my plans were, or do something else. I'm happy to get new ideas.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  11. #41
    GPL License Advocate Moogly is offline
    Alpha MaleRank
    Feb 2008 Join Date
    Vault 101Location
    2,321Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Keep going, there's no shame in doing niche projects. ;)
    Arcturus uses MySQL Connector which is GPL Licensed, therefore Arcturus is a GPL Licensed project and anybody can fork it.

    GPL License ELI5:

    You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions.

  12. #42
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    I agree, I'll keep continuing this as I definitely enjoy it.






    A few updates. It doesn't look spectacular, but in theory the navigator node packet took me hours to figure out as it works slightly different than v9 would. For people who are interested, I played around in Ion trying to get it working and I documented my foundings on the packet, this is 100% my discovery (with thanks to the people who made it possible for me to look into the Lingo scripts): https://pastebin.com/ePtMVXGP

    The "my rooms" section is as easy as v9 but still a nice thing. All data is fetched from the database and thus not static placeholder data. My plan for today is to get room entry working - both public rooms and private rooms - and maybe a start on walking and talking.

    Also due to how extremely "buggy" EF Core is (EF Core won't work with async method and I had to make everything sync in order for it to work properly, don't take buggy too serious but this is definitely something that annoyed me), I decided to switch back to Fluent NHibernate. This doesn't mean getting data is harder, it only means database seeding is a bit... different.

    Basically, I got an interface which is the contract for the seeder classes:

    PHP Code:
    public interface IDataSeeder
        
    {
            
    IEnumerable<objectData get; }

            
    void Seed();
        } 
    (I still have to port this to C# 8.0 since C# 8.0 allows default implementation in interfaces)

    This is an example of a DataSeeder class:

    PHP Code:
    public class RoleDataSeeder IDataSeeder
        
    {
            public 
    IEnumerable<objectData => new[]
            {
                new 
    Role() {Id 1Name "Player"},
            };

            private 
    readonly DbSessionFactory _dbSessionFactory;

            public 
    RoleDataSeeder(DbSessionFactory dbSessionFactory)
            {
                
    _dbSessionFactory dbSessionFactory;
            }

            public 
    void Seed()
            {
                var 
    session _dbSessionFactory.OpenSession();

                if (!
    session.Query<Role>().IsEmpty()) return;
                
                foreach (var 
    obj in Data)
                {
                    
    session.Save(obj);
                }
            }
        } 
    When starting the server, after NHibernate is configured (and the database is created/updated if necessary), it executes the following code:

    PHP Code:
    foreach (var service in _serviceProvider.GetServices<IDataSeeder>())
                {
                    
    service.Seed();
                } 
    For every implementation of IDataSeeder it'll call the Seed function (and execute whatever code is in it). There are no migrations, but NHibernate will keep the database up to date with the code, meaning whenever a new column is added, it'll automatically add it on boot. Boot time will be a bit longer but it shouldn't be too bad.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  13. #43
    Evil Scottish Overlord Joopie is offline
    LegendRank
    Jun 2010 Join Date
    The NetherlandsLocation
    2,772Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Emily View Post
    Also due to how extremely "buggy" EF Core is (EF Core won't work with async method and I had to make everything sync in order for it to work properly, don't take buggy too serious but this is definitely something that annoyed me), I decided to switch back to Fluent NHibernate. This doesn't mean getting data is harder, it only means database seeding is a bit... different.

    (...)

    For every implementation of IDataSeeder it'll call the Seed function (and execute whatever code is in it). There are no migrations, but NHibernate will keep the database up to date with the code, meaning whenever a new column is added, it'll automatically add it on boot. Boot time will be a bit longer but it shouldn't be too bad.
    I find it strange to believe EF Core is buggy. And when you said you can't make the async methods to work, I think it's a problem on your side of the code. Like I said before, async all the way. You can't call a async method in a sync one. It can cause strange side effects and even deadlocks doing so. When doing it right it should work just like the sync methods.

    I also suggest you use some sort of migration tool. Again EF Core has this build in, and I do not know about Hibernation. A big downside, depending on how Hibernate choses how to do so, is that it can wipe or fuckup your database. At first, and while developing on your own, it might be fine. But remember the long terms. Pushing a update will be, just, bad.

    Edit: Some questions:
    1. Why do you want to use default implementations for that? I don't see how a default implementation would be beneficial.
    2. Why is the property Data in your interface? Seems, as far as I can see, that Seed() is enough.


    Join Our RaGEZONE Discord Now!


    Send me a PM | send me a mail

    Still waiting for XenForo to hit RaGEZONE.

  14. #44
    I'll sail away... Emily is offline
    Pink PantherRank
    Oct 2012 Join Date
    The NetherlandsLocation
    2,515Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Quote Originally Posted by Joopie View Post
    I find it strange to believe EF Core is buggy. And when you said you can't make the async methods to work, I think it's a problem on your side of the code. Like I said before, async all the way. You can't call a async method in a sync one. It can cause strange side effects and even deadlocks doing so. When doing it right it should work just like the sync methods.

    I also suggest you use some sort of migration tool. Again EF Core has this build in, and I do not know about Hibernation. A big downside, depending on how Hibernate choses how to do so, is that it can wipe or fuckup your database. At first, and while developing on your own, it might be fine. But remember the long terms. Pushing a update will be, just, bad.

    Edit: Some questions:
    1. Why do you want to use default implementations for that? I don't see how a default implementation would be beneficial.
    2. Why is the property Data in your interface? Seems, as far as I can see, that Seed() is enough.
    As a matter of fact, I did have everything on async (excluding COMPOSER.Compose functions which basically only return a ServerMessage object). IIRC I did read about EF Core not working well with it and several problems relating to it on the internet. It started giving errors on the NAVIGATE packet IIRC for some reason. I could try it again and post the original error but I'm pretty sure it didn't work well.

    I'm not sure if there's something to use but I would say there is so I'll look into the migrations thing. I agree that migrations is the way to go (as most frameworks like that uses migrations).

    1. I don't know either forget I said it I wasn't thinking straight (I don't even know why I said it)
    2. I think more of a leftover from how I wanted to do it first; use a base class where the seed function and DI would be done and you could override the data in the classes and the Seed function would've been always the same (less of the same code). Though I changed it (probably because I had some issues with it, not sure) and I didn't think of removing the data. I agree it isn't necessary though.
    Project Nordlys (Aurora before) reboot:

    http://forum.ragezone.com/f331/asp-n...1/#post8988631

  15. #45
    Moderator Quackster is offline
    ModeratorRank
    Dec 2010 Join Date
    AustraliaLocation
    3,408Posts

    Re: [C#/ASP .NET/DotNet Core] Project Aurora Pro [v7/R38]

    Fair warning, not sure if you know but the mod tool is completely borked in the R38 beta Flash client. The tool will display, but the button to view room chat logs doesn't send any request to the server. You could possibly patch it in the AS3 (if Sulake accidentally broke it) I haven't investigated that far however.
    The Habbo archives: http://alex-dev.org/archive/



Page 3 of 4 FirstFirst 1234 LastLast

Advertisement