Menu
Forums
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Trending
What's new
New posts
New profile posts
Latest activity
Members
Current visitors
New profile posts
Search profile posts
Upgrades
Log in
Register
What's new
Search
Search
Search titles only
By:
All threads
Latest threads
New posts
Trending threads
New posts
Search forums
Menu
Log in
Register
Navigation
Install the app
Install
More options
Contact us
Close Menu
Forums
Server Development
Habbo Retros
Habbo Development
Arcturus Emulator 2.0 - Project Sirius C# | Distributed, Multi Revision, Powerful API + MOAR
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="TheGeneral" data-source="post: 471591" data-attributes="member: 73182"><p>Heya,</p><p></p><p>Figured I'd post here too. As I'm not too active on this forum, I figured maybe someone hasn't seen this yet. <img src="/styles/default/xenforo/smilies/emojione/eek.png" class="smilie" loading="lazy" alt=":eek:" title="Eek! :eek:" data-shortname=":eek:" /></p><p></p><p>I have been working on building a new emulator as the successor to Arcturus, completely from scratch; <strong>Sirius Emulator</strong>. 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.</p><p></p><p>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 <img src="/styles/default/xenforo/smilies/emojione/smile.png" class="smilie" loading="lazy" alt=":)" title="Smile :)" data-shortname=":)" /></p><p></p><p>Sirius will have some very unique and interesting features including:</p><p><strong>Multi Revision Support: </strong>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</p><p><strong>Complete Localization </strong>will allow you to have users change their preferred language. This is propagated all the way to the catalog and pet chatter!</p><p><strong>Advance API </strong>allows you to use all the features of C#, there is literally no limit to what you can do. Checkout some screenshots below!</p><p><strong>Fully Distributed </strong>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.</p><p></p><p>Anyways, here are some features so far:</p><ul> <li data-xf-list-type="ul">Furniture</li> <li data-xf-list-type="ul">Whole bunch of furniture interactions</li> <li data-xf-list-type="ul">Navigator</li> <li data-xf-list-type="ul">Achievements</li> <li data-xf-list-type="ul">Catalog</li> <li data-xf-list-type="ul">BuildersClub</li> <li data-xf-list-type="ul">Crafting</li> <li data-xf-list-type="ul">Marketplace</li> <li data-xf-list-type="ul">TalentTrack</li> <li data-xf-list-type="ul">Trading</li> <li data-xf-list-type="ul">Habbo Club</li> <li data-xf-list-type="ul">HC Gifts</li> <li data-xf-list-type="ul">Payday</li> <li data-xf-list-type="ul">Wireds (Triggers, Effects, Conditions and extras</li> <li data-xf-list-type="ul">Freeze</li> <li data-xf-list-type="ul">Snowboard</li> <li data-xf-list-type="ul">Water Furniture</li> <li data-xf-list-type="ul">Battle Banzai</li> <li data-xf-list-type="ul">Football including accurate ball!</li> <li data-xf-list-type="ul">Bots</li> <li data-xf-list-type="ul">Whole bunch of commands</li> <li data-xf-list-type="ul">Namechanging</li> <li data-xf-list-type="ul">Vouchers</li> <li data-xf-list-type="ul">Mod Tools</li> <li data-xf-list-type="ul">Messenger</li> <li data-xf-list-type="ul">Groups</li> <li data-xf-list-type="ul">Profiles</li> </ul><p>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.</p><p>For example here is the Give Badge command as implemented in Arcturus:</p><p></p><p>[SPOILER="Java Arcturus"][CODE=java]public class BadgeCommand extends Command</p><p>{</p><p> public BadgeCommand()</p><p> {</p><p> super("cmd_badge", Emulator.getTexts().getValue("commands.keys.cmd_badge").split(";"));</p><p> }</p><p></p><p> @Override</p><p> public boolean handle(GameClient gameClient, String[] params) throws Exception</p><p> {</p><p> if(params.length == 1)</p><p> {</p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_username"), RoomChatMessageBubbles.ALERT);</p><p> return true;</p><p> }</p><p> if(params.length == 2)</p><p> {</p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.forgot_badge").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);</p><p> return true;</p><p> }</p><p></p><p> if(params.length == 3)</p><p> {</p><p> Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(params[1]);</p><p></p><p> if(habbo != null)</p><p> {</p><p> if (habbo.addBadge(params[2]))</p><p> {</p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);</p><p> }</p><p> else</p><p> {</p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owned").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);</p><p> }</p><p></p><p> return true;</p><p> }</p><p> else</p><p> {</p><p> try (Connection connection = Emulator.getDatabase().getDataSource().getConnection())</p><p> {</p><p> boolean found;</p><p></p><p> 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"))</p><p> {</p><p> statement.setString(1, params[1]);</p><p> statement.setString(2, params[2]);</p><p> try (ResultSet set = statement.executeQuery())</p><p> {</p><p> found = set.next();</p><p> }</p><p> }</p><p></p><p> if(found)</p><p> {</p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_badge.already_owns").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);</p><p> return true;</p><p> }</p><p> else</p><p> {</p><p> try (PreparedStatement statement = connection.prepareStatement("INSERT INTO users_badges VALUES (null, (SELECT id FROM users WHERE username = ? LIMIT 1), 0, ?)"))</p><p> {</p><p> statement.setString(1, params[1]);</p><p> statement.setString(2, params[2]);</p><p> statement.execute();</p><p> }</p><p></p><p> gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_badge.given").replace("%user%", params[1]).replace("%badge%", params[2]), RoomChatMessageBubbles.ALERT);</p><p> return true;</p><p> }</p><p> }</p><p> catch (SQLException e)</p><p> {</p><p> Emulator.getLogging().logSQLException(e);</p><p> }</p><p> }</p><p> }</p><p></p><p> return true;</p><p> }</p><p>}[/CODE][/SPOILER]</p><p></p><p>And here its for Sirius:</p><p></p><p>[SPOILER="C# Sirius"][CODE=csharp]public class BadgeCommand : ICommand</p><p> {</p><p> private readonly IBadgesService _badgesService;</p><p> public string Key => "badge";</p><p></p><p> public BadgeCommand(IBadgesService badgesService)</p><p> {</p><p> _badgesService = badgesService;</p><p> }</p><p></p><p> public async Task<CommandResult> Handle(IHabbo habbo, string[] parameters)</p><p> {</p><p> if (parameters.Length == 0 || string.IsNullOrWhiteSpace(parameters[0])) return CommandResult.WithErrorStatus("forgot_username");</p><p> if (parameters.Length == 1 || string.IsNullOrWhiteSpace(parameters[1])) return CommandResult.WithErrorStatus("forgot_badge");</p><p> var username = parameters[0];</p><p> var badgeCode = parameters[1];</p><p> var giveBadgeResult = await _badgesService.GiveBadge(username, badgeCode);</p><p> if (giveBadgeResult == BadgeOperationResult.Created) return CommandResult.Ok;</p><p> return CommandResult.WithErrorStatus(ErrorMessageFromBadgeOperationResult(giveBadgeResult));</p><p> }</p><p></p><p> private static string ErrorMessageFromBadgeOperationResult(BadgeOperationResult result) => result switch</p><p> {</p><p> BadgeOperationResult.Created => "ok",</p><p> BadgeOperationResult.UserNotFound => "user_not_found",</p><p> BadgeOperationResult.AlreadyOwned => "already_owned",</p><p> _ => "error"</p><p> };</p><p> }[/CODE][/SPOILER]</p><p></p><p>Simple, concise and easy to follow and understand.</p><p></p><p><strong>Plugins </strong>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:</p><p></p><p>[CODE=csharp]</p><p>public class CommandPluginDefinition : IPluginDefinition</p><p> {</p><p> public string Name => "Command Plugin Example";</p><p> public string Description => "Command Plugin example to demonstrate developing plugins in Sirius";</p><p> public Version Version => new(1, 0);</p><p> public Type PluginClass() => typeof(CommandPlugin);</p><p> }</p><p></p><p> public class CommandPlugin : IPlugin</p><p> {</p><p> public CommandPlugin()</p><p> {</p><p>// Here you could do your own custom stuff you might need.</p><p> }</p><p> }</p><p></p><p> public class PingCommand : ICommand</p><p> {</p><p> public string Key => "ping";</p><p></p><p> public Task<CommandResult> Handle(IHabbo habbo, string[] parameters)</p><p> {</p><p> habbo.Alert("Pong!");</p><p> return Task.FromResult(CommandResult.Ok);</p><p> }</p><p> }[/CODE]</p><p></p><p><img src="https://i.imgur.com/ndkzmXs.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.imgur.com/lAqhA8U.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p></p><p>A bunch of demo plugins including my classic Avatar Poof plugin have been put up online already and can be accessed at <a href="https://github.com/80O/SiriusPlugins/" target="_blank">https://github.com/80O/SiriusPlugins/</a></p><p>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.</p><p></p><p>Here is an example of a Housekeeping I build:</p><p></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/851403188305395732/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p></p><p>And the code:</p><p></p><p>[code=csharp]</p><p> </p><p> @Page "/fetchdata"</p><p></p><p>@using Sirius.Api.Game.User</p><p>@using Sirius.Api.Game.Rooms @Inject IHabboCache HabboCache @Inject IGuestRoomDataRepository GuestRooms</p><p></p><p><h1>Players</h1></p><p></p><p><p>View online players</p></p><p></p><p>@if (_habbos == null)</p><p>{</p><p> <p><em>Loading...</em></p></p><p>}</p><p>else</p><p>{</p><p> <table class="table"></p><p> <thead></p><p> <tr></p><p> <th></th></p><p> <th>Username</th></p><p> <th>Time Online</th></p><p> <th>Current Room</th></p><p> </tr></p><p> </thead></p><p> <tbody></p><p> @foreach (var habbo in _habbos)</p><p> {</p><p> <tr></p><p> <td><img src="https://www.habbo.nl/habbo-imaging/avatarimage?figure=@(habbo.Info.Figure)&headonly=1" /></td></p><p> <td>@habbo.Info.Name</td></p><p> <td></p><p> @{</p><p> var span = DateTime.Now - UnixTimeToDateTime(habbo.Info.LoginTimestamp);</p><p> if (span.Hours > 0)</p><p> @($"{span.Hours} hours, ")</p><p> @($"{span.Minutes} minutes")</p><p> }</p><p> </td></p><p> <td>@{</p><p> if (habbo.CurrentRoom > 0)</p><p> {</p><p> var room = GuestRooms.Get(habbo.CurrentRoom).Result;</p><p> @($"({room.FlatId}): {room.Name}")</p><p> }</p><p> else</p><p> {</p><p> @(" - ")</p><p> }</p><p> }</td></p><p> </tr></p><p> }</p><p> </tbody></p><p> </table></p><p>}</p><p> @code {</p><p> private IHabbo[] _habbos;</p><p></p><p> protected override void OnInitialized()</p><p> {</p><p> _habbos = HabboCache.OnlineHabbos.Values.ToArray();</p><p> }</p><p></p><p> private DateTime UnixTimeToDateTime(long unixtime)</p><p> {</p><p> var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);</p><p> dateTime = dateTime.AddMilliseconds(unixtime).ToLocalTime();</p><p> return dateTime;</p><p> }</p><p>}</p><p>[/code]</p><p></p><p>Demo hotel is up at <a href="https://sirius.arcturus.pw" target="_blank">https://sirius.arcturus.pw</a> It might be down at sometimes, then I might work on it. Its live with both the flash client and nitro.</p><p></p><p>Thx!</p><p></p><p>Wesley</p><p></p><p>More screenshots after the spoiler or checkout <a href="https://arcturus.pw" target="_blank">https://arcturus.pw</a> for even moar amazing screenshots. :</p><p>[spoiler]</p><p>[URL unfurl="true"]https://i.gyazo.com/e3c9e4d93a37efa2429d00023cd1d988.mp4[/URL]</p><p>[URL unfurl="true"]https://i.gyazo.com/0e2cd37c6fc93351d6f30741a0e7ac49.mp4[/URL]</p><p><img src="https://i.gyazo.com/ca809aa00ac3639ef9c8db5fd9ac17c5.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/9ec4a5065c0455df80dedd01e45bf9d1.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/3409be4d199f01afc21c0f907a6bd546.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/5710223bc095cdbc5c877e4eb4f9dc10.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/1c9acf365140e799a2e88336cf2a5a5f.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/31d656204fded3d7db77944877a85851.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/d880aab0212cd69d7a6bdc796b9c2e42.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/d05cb12a9b73dc5e043bbf6433f4803b.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/855562915171532850/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/7e694681c18f6aa0561bd72e474928da.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/fc712df7ad6230d678bce6e2119badf1.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://media.discordapp.net/attachments/736318004282785824/873196130555531285/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/873196776558047302/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/874626652355846224/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/874626870413496320/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/874627022842904587/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/877295054371291216/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/3ba98dd943c3cab49d022c5be5caa6a0.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/fa29da2ead43ea6f01595a36b5f9831e.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/70acbad46fc4c3e43bc091f2c67ad4b4.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/9f09819a4417984db39bf5789fdaca50.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/e1cf3b642a6cb43ec0a9cf587ddccb87.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/0ff0f6a29599e38e3241107273c35302.gif" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/855218339475095572/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://cdn.discordapp.com/attachments/736318004282785824/831534163009732639/unknown.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p><img src="https://i.gyazo.com/0c8ca875a898fc8e7711ea0010a524fa.png" alt="" class="fr-fic fr-dii fr-draggable " style="" /></p><p>[/spoiler]</p></blockquote><p></p>
[QUOTE="TheGeneral, post: 471591, member: 73182"] 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; [B]Sirius Emulator[/B]. 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: [B]Multi Revision Support: [/B]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 [B]Complete Localization [/B]will allow you to have users change their preferred language. This is propagated all the way to the catalog and pet chatter! [B]Advance API [/B]allows you to use all the features of C#, there is literally no limit to what you can do. Checkout some screenshots below! [B]Fully Distributed [/B]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: [LIST] [*]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 [/LIST] 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: [SPOILER="Java Arcturus"][CODE=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; } }[/CODE][/SPOILER] And here its for Sirius: [SPOILER="C# Sirius"][CODE=csharp]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" }; }[/CODE][/SPOILER] Simple, concise and easy to follow and understand. [B]Plugins [/B]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: [CODE=csharp] 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); } }[/CODE] [IMG]https://i.imgur.com/ndkzmXs.png[/IMG] [IMG]https://i.imgur.com/lAqhA8U.png[/IMG] A bunch of demo plugins including my classic Avatar Poof plugin have been put up online already and can be accessed at [URL]https://github.com/80O/SiriusPlugins/[/URL] 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: [IMG]https://cdn.discordapp.com/attachments/736318004282785824/851403188305395732/unknown.png[/IMG] And the code: [code=csharp] @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/avatarimage?figure=@(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; } } [/code] Demo hotel is up at [URL]https://sirius.arcturus.pw[/URL] 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 [URL]https://arcturus.pw[/URL] for even moar amazing screenshots. : [spoiler] [URL unfurl="true"]https://i.gyazo.com/e3c9e4d93a37efa2429d00023cd1d988.mp4[/URL] [URL unfurl="true"]https://i.gyazo.com/0e2cd37c6fc93351d6f30741a0e7ac49.mp4[/URL] [IMG]https://i.gyazo.com/ca809aa00ac3639ef9c8db5fd9ac17c5.gif[/IMG] [IMG]https://i.gyazo.com/9ec4a5065c0455df80dedd01e45bf9d1.gif[/IMG] [IMG]https://i.gyazo.com/3409be4d199f01afc21c0f907a6bd546.gif[/IMG] [IMG]https://i.gyazo.com/5710223bc095cdbc5c877e4eb4f9dc10.gif[/IMG] [IMG]https://i.gyazo.com/1c9acf365140e799a2e88336cf2a5a5f.gif[/IMG] [IMG]https://i.gyazo.com/31d656204fded3d7db77944877a85851.gif[/IMG] [IMG]https://i.gyazo.com/d880aab0212cd69d7a6bdc796b9c2e42.gif[/IMG] [IMG]https://i.gyazo.com/d05cb12a9b73dc5e043bbf6433f4803b.gif[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/855562915171532850/unknown.png[/IMG] [IMG]https://i.gyazo.com/7e694681c18f6aa0561bd72e474928da.gif[/IMG] [IMG]https://i.gyazo.com/fc712df7ad6230d678bce6e2119badf1.gif[/IMG] [IMG]https://media.discordapp.net/attachments/736318004282785824/873196130555531285/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/873196776558047302/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/874626652355846224/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/874626870413496320/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/874627022842904587/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/877295054371291216/unknown.png[/IMG] [IMG]https://i.gyazo.com/3ba98dd943c3cab49d022c5be5caa6a0.gif[/IMG] [IMG]https://i.gyazo.com/fa29da2ead43ea6f01595a36b5f9831e.gif[/IMG] [IMG]https://i.gyazo.com/70acbad46fc4c3e43bc091f2c67ad4b4.gif[/IMG] [IMG]https://i.gyazo.com/9f09819a4417984db39bf5789fdaca50.gif[/IMG] [IMG]https://i.gyazo.com/e1cf3b642a6cb43ec0a9cf587ddccb87.gif[/IMG] [IMG]https://i.gyazo.com/0ff0f6a29599e38e3241107273c35302.gif[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/855218339475095572/unknown.png[/IMG] [IMG]https://cdn.discordapp.com/attachments/736318004282785824/831534163009732639/unknown.png[/IMG] [IMG]https://i.gyazo.com/0c8ca875a898fc8e7711ea0010a524fa.png[/IMG] [/spoiler] [/QUOTE]
Insert quotes…
Verification
Post reply
Forums
Server Development
Habbo Retros
Habbo Development
Arcturus Emulator 2.0 - Project Sirius C# | Distributed, Multi Revision, Powerful API + MOAR
Top