Arcturus Emulator 2.0 - Project Sirius C# | Distributed, Multi Revision, Powerful API + MOAR

TheGeneral

Member
Dec 27, 2016
37
38
Heya,

Figured I'd post here too. As I'm not too active on this forum, I figured maybe someone hasn't seen this yet. :eek:

I have been working on building a new emulator as the successor to Arcturus, completely from scratch; Sirius Emulator. With the release of .NET Core and its cross platform compatibility, it was an excellent choice to use C# as the language to write this in.

As the Arcturus (and all crappy renames based off it, like MS), the API got convoluted, ugly and just overall messy to use. Kudos to everyone who managed to create some of those amazing plugins with it. With the new emulator I want to provide a clean, easy to use API to implement your own custom features and to hook in or completely replace parts of the emulator without having to touch any of the core code. Hate to break it to you, its still easy to mess things up if you don't know what youre doing :)

Sirius will have some very unique and interesting features including:
Multi Revision Support: By default Sirius supports Nitro as well as good ol' flash. You can simply build against the API and implement your own client type. Perhaps command line? Or your own custom client in Javascript
Complete Localization will allow you to have users change their preferred language. This is propagated all the way to the catalog and pet chatter!
Advance API allows you to use all the features of C#, there is literally no limit to what you can do. Checkout some screenshots below!
Fully Distributed allows you to scale over multiple servers if needed. The benefit of this is that I can also run parts of the emulator on my own to test & debug.

Anyways, here are some features so far:
  • Furniture
  • Whole bunch of furniture interactions
  • Navigator
  • Achievements
  • Catalog
  • BuildersClub
  • Crafting
  • Marketplace
  • TalentTrack
  • Trading
  • Habbo Club
  • HC Gifts
  • Payday
  • Wireds (Triggers, Effects, Conditions and extras
  • Freeze
  • Snowboard
  • Water Furniture
  • Battle Banzai
  • Football including accurate ball!
  • Bots
  • Whole bunch of commands
  • Namechanging
  • Vouchers
  • Mod Tools
  • Messenger
  • Groups
  • Profiles
With Sirius, the quality of the code, easy of maintainability has the highest priority. A lot of time is spend in optimizing and improving the APIs which pays back in the speed & ease of development.
For example here is the Give Badge command as implemented in Arcturus:

Java:
public class BadgeCommand extends Command
{
    public BadgeCommand()
    {
        super("cmd_badge", Emulator.getTexts().getValue("commands.keys.cmd_badge").split(";"));
    }

     @Override
    public boolean handle(GameClient gameClient, String[] params) throws Exception
    {
        if(params.length == 1)
        {
            gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_username"), RoomChatMessageBubbles.ALERT);
            return true;
        }
        if(params.length == 2)
        {
            gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_badge").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
            return true;
        }

        if(params.length == 3)
        {
            Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]);

            if(habbo != null)
            {
                if (habbo.addBadge(params[2]))
                {
                    gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);
                }
                else
                {
                    gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owned").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);
                }

                return true;
            }
            else
            {
                try (Connection connection = Emulator.getDatabase().getDataSource().getConnection())
                {
                    boolean found;

                    try (PreparedStatement statement = connection.prepareStatement("SELECT badge_code FROM users_badges INNER JOIN users ON users.id = user_id WHERE users.username = ? AND badge_code = ? LIMIT 1"))
                    {
                        statement.setString(1, params[1]);
                        statement.setString(2, params[2]);
                        try (ResultSet set = statement.executeQuery())
                        {
                            found = set.next();
                        }
                    }

                    if(found)
                    {
                        gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owns").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);
                        return true;
                    }
                    else
                    {
                        try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges VALUES (null, (SELECT id FROM users WHERE username = ? LIMIT 1), 0, ?)"))
                        {
                            statement.setString(1, params[1]);
                            statement.setString(2, params[2]);
                            statement.execute();
                        }

                        gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);
                        return true;
                    }
                }
                catch (SQLException e)
                {
                    Emulator.getLogging().logSQLException(e);
                }
            }
        }

        return true;
    }
}

And here its for Sirius:

C#:
public class BadgeCommand : ICommand
    {
        private readonly IBadgesService _badgesService;
        public string Key => "badge";

        public BadgeCommand(IBadgesService badgesService)
        {
            _badgesService = badgesService;
        }

        public async Task<CommandResult> Handle(IHabbo habbo, string[] parameters)
        {
            if (parameters.Length == 0 || string.IsNullOrWhiteSpace(parameters[0])) return CommandResult.WithErrorStatus("forgot_username");
            if (parameters.Length == 1 || string.IsNullOrWhiteSpace(parameters[1])) return CommandResult.WithErrorStatus("forgot_badge");
            var username = parameters[0];
            var badgeCode = parameters[1];
            var giveBadgeResult = await _badgesService.GiveBadge(username, badgeCode);
            if (giveBadgeResult == BadgeOperationResult.Created) return CommandResult.Ok;
            return CommandResult.WithErrorStatus(ErrorMessageFromBadgeOperationResult(giveBadgeResult));
        }

        private static string ErrorMessageFromBadgeOperationResult(BadgeOperationResult result) => result switch
        {
            BadgeOperationResult.Created => "ok",
            BadgeOperationResult.UserNotFound => "user_not_found",
            BadgeOperationResult.AlreadyOwned => "already_owned",
            _ => "error"
        };
    }

Simple, concise and easy to follow and understand.

Plugins are easy to make, easy to maintain and use. You don't need to worry about getting to the right services, just inject them and let the magic happen. The same way around to extend or add in new functionality. By just simply implementing the interface, Sirius will automatically pick it up. Here is an example to create a simple command:

C#:
public class CommandPluginDefinition : IPluginDefinition
    {
        public string Name => "Command Plugin Example";
        public string Description => "Command Plugin example to demonstrate developing plugins in Sirius";
        public Version Version => new(1, 0);
        public Type PluginClass() => typeof(CommandPlugin);
    }

    public class CommandPlugin : IPlugin
    {
        public CommandPlugin()
        {
// Here you could do your own custom stuff you might need.
        }
    }

    public class PingCommand : ICommand
    {
        public string Key => "ping";

        public Task<CommandResult> Handle(IHabbo habbo, string[] parameters)
        {
            habbo.Alert("Pong!");
            return Task.FromResult(CommandResult.Ok);
        }
    }

ndkzmXs.png

lAqhA8U.png


A bunch of demo plugins including my classic Avatar Poof plugin have been put up online already and can be accessed at
Remember I said you can use anything C# has to offer? That includes server side Blazor applications! No need to hassle with stupid RCON, AJAX or other kinds of http API calls. Simply inject the services you need in your blazor component and let the magic happen.

Here is an example of a Housekeeping I build:

unknown.png


And the code:

C#:
 @Page "/fetchdata"

@using Sirius.Api.Game.User
@using Sirius.Api.Game.Rooms @Inject IHabboCache HabboCache @Inject IGuestRoomDataRepository GuestRooms

<h1>Players</h1>

<p>View online players</p>

@if (_habbos == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th></th>
                <th>Username</th>
                <th>Time Online</th>
                <th>Current Room</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var habbo in _habbos)
            {
                <tr>
                    <td><img src="https://www.habbo.nl/habbo-imaging/[email protected](habbo.Info.Figure)&headonly=1" /></td>
                    <td>@habbo.Info.Name</td>
                    <td>
                        @{
                            var span = DateTime.Now - UnixTimeToDateTime(habbo.Info.LoginTimestamp);
                            if (span.Hours > 0)
                                @($"{span.Hours} hours, ")
                            @($"{span.Minutes} minutes")
                        }
                    </td>
                    <td>@{
                            if (habbo.CurrentRoom > 0)
                            {
                                var room = GuestRooms.Get(habbo.CurrentRoom).Result;
                                @($"({room.FlatId}): {room.Name}")
                            }
                            else
                            {
                                @(" - ")
                            }
                        }</td>
                </tr>
            }
        </tbody>
    </table>
}
 @code {
    private IHabbo[] _habbos;

    protected override void OnInitialized()
    {
        _habbos = HabboCache.OnlineHabbos.Values.ToArray();
    }

    private DateTime UnixTimeToDateTime(long unixtime)
    {
        var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
        dateTime = dateTime.AddMilliseconds(unixtime).ToLocalTime();
        return dateTime;
    }
}

Demo hotel is up at It might be down at sometimes, then I might work on it. Its live with both the flash client and nitro.

Thx!

Wesley

More screenshots after the spoiler or checkout for even moar amazing screenshots. :
ca809aa00ac3639ef9c8db5fd9ac17c5.gif

9ec4a5065c0455df80dedd01e45bf9d1.gif

3409be4d199f01afc21c0f907a6bd546.gif

5710223bc095cdbc5c877e4eb4f9dc10.gif

1c9acf365140e799a2e88336cf2a5a5f.gif

31d656204fded3d7db77944877a85851.gif

d880aab0212cd69d7a6bdc796b9c2e42.gif

d05cb12a9b73dc5e043bbf6433f4803b.gif

unknown.png

7e694681c18f6aa0561bd72e474928da.gif

fc712df7ad6230d678bce6e2119badf1.gif

unknown.png

unknown.png

unknown.png

unknown.png

unknown.png

unknown.png

3ba98dd943c3cab49d022c5be5caa6a0.gif

fa29da2ead43ea6f01595a36b5f9831e.gif

70acbad46fc4c3e43bc091f2c67ad4b4.gif

9f09819a4417984db39bf5789fdaca50.gif

e1cf3b642a6cb43ec0a9cf587ddccb87.gif

0ff0f6a29599e38e3241107273c35302.gif

unknown.png

unknown.png

0c8ca875a898fc8e7711ea0010a524fa.png
 

Diddy

Member
Aug 14, 2011
90
14
Exciting to have followed development, the progress and the work you’ve put into it is insane.

Looking forward to seeing it released and getting my hands on it!

Keep it up Wes!!
 

GooGoo

New Member
Jan 20, 2021
10
5
I won't be making an RP. Maybe someone else will use the API to create RP plugins but I have no intention to make one.
Yea. I figured that would be the case but nonetheless, awesome release keep up the good work! good luck with your project! and is there an ETA?
 

Brad

Well-Known Member
Jun 5, 2012
2,304
971
Hi,

Development seems promising, by your plugin feature does look rather handy, but disappointing this won't be open source but at the same time I do understand why.

Best of luck, looking forward to seeing updates.
 

Leader

Instinct <3
Aug 24, 2012
918
157
Your last project wasn't open-source, right? Just look at that for example why it's disappointing. Open development is always better.
The best projects in the community stem from closed-source work that got leaked. Butterfly, Comet, Plus...just to name a few.

Open source is very important and I can't see why people wouldn't want to give back to the community that most likely inspired their passion, but it doesn't make the quality of work better; typically quality goes down when more developers are added.
 

TheGeneral

Member
Dec 27, 2016
37
38
Your last project wasn't open-source, right? Just look at that for example why it's disappointing. Open development is always better.
You are wrong / misinformed. Please stop making assumptions. Arcturus was open source for a couple years up to a point where there were no contributions happening anymore and people started to use it as a base for renames, which was clearly not allowed as stated on the repository back then.

Again, why is it disappointing? Because the development is dead? Yeah well no shit sherlock, blame the people who started to decompile & rename and pretty much demotivated me to continue working on it. Disappointing because nobody contributed? Yeah well I was disappointed with that too, for the amount of people that were shouting open source is better so everyone can contribute yet only a handful of people submitted pull requests to the original repository. I wrote a pile of shit, and you can't polish a turd when its oozing out all over your servers.

No open development is not always better. People just want an easy way to add their name for a quick claim to fame. If people really wanted to work on an emulator, they dont need other people to do the work for them. They would just start their own emulator from scratch instead. But apparently thats too much effort so its just easier to copy someone elses work.
Post automatically merged:

The best projects in the community stem from closed-source work that got leaked. Butterfly, Comet, Plus...just to name a few.

Open source is very important and I can't see why people wouldn't want to give back to the community that most likely inspired their passion, but it doesn't make the quality of work better; typically quality goes down when more developers are added.
Oh I can tell you, because everything is a shit ton of work and time consuming to properly implement and when people nick your work, its demotivating as hell. People see it happening to other peoples projects so they dont even bother starting anymore because it will end up stolen / renamed anyways (because thats what we do around here, some say). Its shit and the community just ruined themselves by not saying, "yo stealing is not cool, you wouldn't want your work to be stolen either" Some have said it and just received a big fuck you as a thank you.
 

Brad

Well-Known Member
Jun 5, 2012
2,304
971
The best projects in the community stem from closed-source work that got leaked. Butterfly, Comet, Plus...just to name a few.

Open source is very important and I can't see why people wouldn't want to give back to the community that most likely inspired their passion, but it doesn't make the quality of work better; typically quality goes down when more developers are added.
Open-source doesn't mean adding more developers to the same project, it opens it up to more support and development which is exactly what we need right now due to Habbo as a whole dying. The last thing we need is a closed source project for something that's going to have no one playing.

You are wrong / misinformed. Please stop making assumptions. Arcturus was open source for a couple years up to a point where there were no contributions happening anymore and people started to use it as a base for renames, which was clearly not allowed as stated on the repository back then.

Again, why is it disappointing? Because the development is dead? Yeah well no shit sherlock, blame the people who started to decompile & rename and pretty much demotivated me to continue working on it. Disappointing because nobody contributed? Yeah well I was disappointed with that too, for the amount of people that were shouting open source is better so everyone can contribute yet only a handful of people submitted pull requests to the original repository. I wrote a pile of shit, and you can't polish a turd when its oozing out all over your servers.

No open development is not always better. People just want an easy way to add their name for a quick claim to fame. If people really wanted to work on an emulator, they dont need other people to do the work for them. They would just start their own emulator from scratch instead. But apparently thats too much effort so its just easier to copy someone elses work.
Post automatically merged:


Oh I can tell you, because everything is a shit ton of work and time consuming to properly implement and when people nick your work, its demotivating as hell. People see it happening to other peoples projects so they dont even bother starting anymore because it will end up stolen / renamed anyways (because thats what we do around here, some say). Its shit and the community just ruined themselves by not saying, "yo stealing is not cool, you wouldn't want your work to be stolen either" Some have said it and just received a big fuck you as a thank you.
Basing a whole development pause due to renames is just a lie, I understand from your point it's frustrating with it being your work but it's just an excuse, if you really wanted something to last and thrive you know open-source would be better. People probably didn't want to contribute just due to it being JAVA or the audience you're targeting.

You can't say open-source isn't better just due to the fact your last project didn't go to plan.

Anyhow, it's your development but I don't see this going much further than a few people if it even gets completed.
 

Gabrielle

New Member
Jan 23, 2016
7
10
I thought The General stopped with this development because he was raging on people?? Anyways I'm sure eventually people will get code unless this won't be released in which I don't see the point of this thread.
 

Leader

Instinct <3
Aug 24, 2012
918
157
All of the hate this man is receiving is precisely why the bulk of developers abandoned the scene years ago.

Nobody respects work private nor open source and yet everyone expects people to go above and beyond to fill the wishes of "the community" which has a hard time opening Google, let alone making a helpful bug report or merge request.

All of the hate is going to lead to TheGeneral making some easy money off of private work because nobody has to contribute for free 🤣
 

Brad

Well-Known Member
Jun 5, 2012
2,304
971
All of the hate this man is receiving is precisely why the bulk of developers abandoned the scene years ago.

Nobody respects work private nor open source and yet everyone expects people to go above and beyond to fill the wishes of "the community" which has a hard time opening Google, let alone making a helpful bug report or merge request.

All of the hate is going to lead to TheGeneral making some easy money off of private work because nobody has to contribute for free 🤣
Hate? Constructive feedback is not hate. Nobody expects him to go above and beyond for the community, exactly why open source would mean that he gets more support.

You think developers left because of hate? 🤣🤣
 

TheGeneral

Member
Dec 27, 2016
37
38
Stop thinking there are amazing programmers in this community. There aren't. Its all a pain in the ass to manage and people get upset when you decline their pull requests because you'd have to fix a dozen other issues before it being mergeable is not something I want to deal with.

From this comment section its clear that all people want is code so they can just rename it or edit it. If you want code, go download butterfly, as thats released by Maritnmine, Use comet as that was released by Leon ( , Github seems to have been removed?), Use IDK emulator by Steffchef.

But no, those are considered old and people want the latest. Well here is something for you, the Habbo game logic hasnt changed much over the past 15 years, so it doesnt matter if it was written yesterday or 5 years ago. If you think its old, then fix itu p, I mean you're the one who has been pushing for open source to aquire the code.

Okay well if you want something more recent; why not start contributing to Chloes Cortex Server ( ) ? Even Morningcrap is pretty much dead.

Sirius will come with a massive API which you could even use to write your own emulator if you wanted to. You just have to add in the data loading and networking and you'd be set.

You must be registered for see images attach
 

Users who are viewing this thread

Top