TheGeneral
Active Member
- Dec 27, 2016
- 149
- 166
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.
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:
For example here is the Give Badge command as implemented in Arcturus:
And here its for Sirius:
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:
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:
And the code:
Demo hotel is up at
Thx!
Wesley
More screenshots after the spoiler or checkout
Figured I'd post here too. As I'm not too active on this forum, I figured maybe someone hasn't seen this yet.
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
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);
}
}
A bunch of demo plugins including my classic Avatar Poof plugin have been put up online already and can be accessed at
You must be registered for see links
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:
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/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;
}
}
Demo hotel is up at
You must be registered for see links
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
You must be registered for see links
for even moar amazing screenshots. :
You must be registered for see links
You must be registered for see links