Sadie: A clean code Habbo emulator

habtard

Member
Jan 30, 2020
32
30
You must be registered for see images attach


Discord (live updates):

Introduction
Sadie is a clean code emulation server targeting the latest PRODUCTION release of Habbo. It's written in C# / .NET core with Windows and Linux support in mind. The repository has received over 1,000 commits and development is still ongoing.

Project Goals
To provide a clean, stable emulator base for future reference, for myself or anyone who wants one.

Why another development?
Its been in active development for 2 years so its not fleeting. I started it before I quit habbo. The release of the Nitro client motivated me to finish it. Even though I don't play anymore, I wanted to finish it.

What's finished?
All core functionality is pretty much there. You can login, create rooms, talk, browse catalog, buy furniture, place and move the furniture, assign rights, send friend requests, set relationships, actions, dance, signs, respect, and more. It would be easier to describe what's not done.

Why post now?
Its reaching a point in its development where it can be tested and showcased.

See below for a few screenshots.
You must be registered for see images attach



You must be registered for see images attach


You must be registered for see images attach
Post automatically merged:

Few more updates since yesterday

You must be registered for see images attach


Can't upload screen casts here as their too big so check discord for those.
Post automatically merged:

Back with another daily update.

Lots of refactoring, improvements to room tile state management, bug fixes and more.
See commits below;

You must be registered for see images attach


Automatic Testing
On each push to develop, a docker container will now also be span up to run the unit tests which will enforce standards going forward

You must be registered for see images attach

Post automatically merged:

Refactored all of the event handlers that read data today (50+ classes took a while), data reading now done via a singleton parser class for each event.

You must be registered for see images attach

Post automatically merged:

Highlights

Merged 150ish commits to main from 0.7
Anything below is now 0.8 tag

  • Fixed a few bugs reported via our testers.
  • Did a ton of refactoring.
  • Fixed some bugs with player subscription expirations
  • Players can now purchase club memberships
  • Added catalog page serializer for HC layout

You must be registered for see images attach


You must be registered for see images attach



Did a bit of work on stacking items, still needs some work though, I also want to refactor how room tile state for quicker mutation

You must be registered for see images attach


See discord #updates for live commit updates.
 

Attachments

  • 1711734519995.png
    1711734519995.png
    320.2 KB · Views: 143
  • 1711734545699.png
    1711734545699.png
    146.8 KB · Views: 295
Last edited:

TheGeneral

Active Member
Dec 27, 2016
149
164
Good luck! More people starting .NET emulators recently, great to see!

What are you using for your database? Simple mysql connection or an ORM?

Couple personal suggestions:
Split your parsers and DTOs. Then you can abstract away your networking part and more easily run simulations / tests.
You might want to consider code generation for your DTO. Saves you a lot of time writing ReadInt, ReadString.
Consider using an auto DI scanning library so you dont need to manually add each new services.
 

habtard

Member
Jan 30, 2020
32
30
Good luck! More people starting .NET emulators recently, great to see!

What are you using for your database? Simple mysql connection or an ORM?

Couple personal suggestions:
Split your parsers and DTOs. Then you can abstract away your networking part and more easily run simulations / tests.
You might want to consider code generation for your DTO. Saves you a lot of time writing ReadInt, ReadString.
Consider using an auto DI scanning library so you dont need to manually add each new services.

Thanks! ADO.NET which I've tried to abstract down with a base class etc (see & ), its very verbose, something like or maybe even entity framework could really help with not writing so much code for that.

Yep, adding parsers was one step to reducing the coupling so eventually I can seperate the responsibilities like you describe.

Also yeah, using something like reflection to recursively register the events would be much easier as its an ever growing complexity otherwise, will look into this soon.

It's good to see people being constructive.
Post automatically merged:

Few more updates

Did some work on club offers, now loading them from the database.

You must be registered for see images attach

You must be registered for see images attach

You must be registered for see images attach


Added (adds extension methods to M.E.DI) for easier service registration:

You must be registered for see images attach

Post automatically merged:

Refactored events so each one declares its packet identifier via a property (auto mapping).

You must be registered for see images attach

Post automatically merged:

Bit off topic... I wanted to improve code quality and enforce certain rules for Sadie but couldn't find anything better than a basic linter.

I spent some time last night writing a really rough C# analyzer, it uses the Roslyn .NET compiler and provides abstractions for things like class and individual method line count, parameter counts, etc

It runs off a config file like so:
You must be registered for see images attach


zsh alias for pre-commit
You must be registered for see images attach


It returns the suggestions count as its exit code (!= 0 will fail) for things like
You must be registered for see images attach


Back on topic...

Commands now define their own trigger keyword via an attribute, instead of defining a collection map.

You must be registered for see images attach


Other highlights
  • Done a ton of refactoring with suggestions from the code-quality-checker.
  • Started moving catalog packet writers to shared serializers so the code stays DRY
  • Spent some time playing with Entity Framework, will (probably?) switch Sadie to it soon.
Post automatically merged:

Spent the day working through some refactoring, room paint settings, and catalog front page items.

Packets now pass front page items, loads from db, etc:
You must be registered for see images attach


You must be registered for see images attach



Room painting done, wall and floor thickness, as well as paint for floor, wall and landscape (see discord for screen cast, can't upload), plus a few other trello items.
Post automatically merged:

Busy upgrading a few things with my set up today but a few commits:

You must be registered for see images attach

Post automatically merged:

Working on lots of paint related stuff, fixing a few bugs, added a few catalogue page serializers.

Starting implementing Entity Framework, which cleared up a lot of boilerplate for the ADO stuff. It still exists, but its on its way out.

Even though EF is a repository pattern I'm keeping the repository classes for testing / mock ability and separation concerns.

Lengthy DAO classes are now gone and repository classes are now cleaner as a result

You must be registered for see images attach

You must be registered for see images attach


Will move all the other stuff over to use it in the next few days and drop ADO.NET for good.
Post automatically merged:

More updates today

Moved all of furniture, catalogue (items, pages, front page items, etc), and navigator to Entity Framework. All that's left now is player and rooms old data access layer then ADO.NET is gone.

This is taking some time to write up all the models and configure the relationships, and I don't want to get distracted so its all I'm focusing on right now. New features will come but the transition to EF core was a must for Sadie which is getting there...

You must be registered for see images attach


Players and rooms are huge in terms of tech debt. They hold more data access related code than all other projects combined, but I'll be tackling those in the coming days.
Post automatically merged:

April 7th, 2024
  • The EF transition is fully complete for room project
  • Separated persistent and BL entities using auto mapper
  • Done a ton of refactoring in response to the EF upgrade
  • Started migrating players project to EF (about 10%)

Plan for the next few weeks will be finishing EF transition, more refactoring and stabilisation work, then maybe an open beta.
Post automatically merged:

April 8th
  • EF transition is complete solution wide
Post automatically merged:

April 9th
  • Dropped tuples project wide for .NET 8's
  • New permission system (roles now many to many, player can be many roles).
  • Improved enumeration parsing with description attributes
  • Lots more refactoring and clean up work
Post automatically merged:

April 10th
  • Refactored entire solution
  • Got migrations generating via EF
  • Can now lay down on lay able furniture.
  • Fixed a bug where status doesn't update coming off chair
  • Started working on furniture interactions (clicking)

You must be registered for see images attach

You must be registered for see images attach
 

Attachments

  • 1711963971263.png
    1711963971263.png
    759 KB · Views: 23
  • 1712075663180.png
    1712075663180.png
    143.7 KB · Views: 22
  • 1712155331542.png
    1712155331542.png
    68.3 KB · Views: 18
Last edited:

habtard

Member
Jan 30, 2020
32
30
April 11 & 12th
  • Brought in new contributors
  • Lots of refactoring
  • Multi tile furniture now works well
  • Wrote some new unit tests

You must be registered for see images attach

Post automatically merged:

April 13th
  • Moved all game constants to the database
  • Added a development mode to ignore SSO security
  • Can now set welcome messages for players
  • More unit tests & refactoring
  • Brought in more developers
Post automatically merged:

April 14th
  • Rewrote walking algorithm
  • Decoupled SSO tokens to its own table
  • Added a CONTRIBUTING.md
  • Made a wiki for code styles ( )

In the next week or two, I'm planning on open sourcing Sadie.
I've been working on a few projects to make it more usable when released.

Includes;
  • A dedicated CMS written in Svelte Kit
  • A REST API written in GO
  • A schema converter script written in PHP

You must be registered for see images attach
 
Last edited:

habtard

Member
Jan 30, 2020
32
30
April 15 & 16th
  • Added option validators for configuration (@Damien)
  • Switched fleck for dotnetty
  • Lots of work on the CMS & API
  • Some work on the schema converter too.

Schema converter is a lot of work, some data is difficult to copy because of the differences in structure, I've managed to convert everything I've tried so far except permissions, because of their different names and weird structure.

Sadie works many to many, players can have many roles, a role can have many permissions etc. I'll look closer at this when its time to release. Check out our discord for more up to date changes as I'm probably forgetting some stuff here.
 

dominic

Active Member
Dec 16, 2011
175
84
why not use EFCore?
why use DotNetty when .net core offers a perfectly good TCP socket framework internally? (makes you able to support both WS and TCP with the same handlers)

also remember Nitro is iffy, so you can't build it around Nitro and expect it to work with Air (for example)
 

habtard

Member
Jan 30, 2020
32
30
why not use EFCore?
why use DotNetty when .net core offers a perfectly good TCP socket framework internally? (makes you able to support both WS and TCP with the same handlers)

also remember Nitro is iffy, so you can't build it around Nitro and expect it to work with Air (for example)
1. We've transitioned to EF.
2. Its a nice way to achieve non-blocking, asynchronous I/O, provides a larger abstraction than if that's what you meant? .NETTY is even easier to align your pipelines so WS connections get upgraded and treated like TCP.

Nitro is iffy? I'd like to hear more...
 
Last edited:

LeChris

Proverbs 3:5
Sep 30, 2013
2,786
1,395
1. We've transitioned to EF.
2. Why use .NETTY? Its a nice way to achieve non-blocking, asynchronous I/O, provides a larger abstraction than if that's what you meant? .NETTY is even easier to align your pipelines so WS connections get upgraded and treated like TCP.

Nitro is iffy? I'd like to hear more...
Nitro doesn't implement everything correctly but it's not really a big deal since it's most of the way there.

Why is Air even brought up? Nitro is mobile compatible and is better than a downloaded app, just seems like a silly thing to chase Sulake for an inferior experience
 

Damien

Don't need glasses if you can C#
Feb 26, 2012
434
647
I think he's refering to the Flash client in general.

While Nitro is amazing, you're right in saying it's not completely accurate, and since it's goal is to mimic the flash client as close as possible, we too should be targeting the flash client first.

By doing this we can better identify what Nitro is doing wrong and help Nitro get closer to replicating the flash client. After all this is a Habbo emulator, it's purpose is to emulate as much of Habbos server as possible, and if a new client comes out with a more accurate packet handler than Nitro at least we don't have to refactor the emulator because we've coded it around Nitros short comings.
 
Last edited:

dominic

Active Member
Dec 16, 2011
175
84
I think he's refering to the Flash client in general.

While Nitro is amazing, you're right in saying it's not completely accurate, and since it's goal is to mimic the flash client as close as possible, we too should be targeting the flash client first.

By doing this we can better identify what Nitro is doing wrong and help Nitro get closer to replicating the flash client. After all this is a Habbo emulator, it's purpose is to emulate as much of Habbos server as possible, and if a new client comes out with a more accurate packet handler than Nitro at least we don't have to refactor the emulator because we've coded it around Nitros short comings.
Yeah, the flash client definitely serves as a good base, for testing.
Nitro was built around Arc/MS which did do a lot eh to make it work :-D.

Yeah - DotNetty doesn't cut it for me, because you have to "make your own" http protocol initially, which .net web already does for you and then expands on that protocol with the WebSocket class - pretty easy tbf.

EDIT1:
(I think Netty itself did introduce a HttpHandler - unsure whether or not DotNetty introduced this as well)

EDIT2:
Well technically speaking, Air can still be used as a client for players to use (no its not in-browser or on mobile) but it does the job - aaaaaand you can pretty much recompile it out-of-the-box. :)
 
Last edited:

habtard

Member
Jan 30, 2020
32
30
Yeah, the flash client definitely serves as a good base, for testing.
Nitro was built around Arc/MS which did do a lot eh to make it work :-D.

Yeah - DotNetty doesn't cut it for me, because you have to "make your own" http protocol initially, which .net web already does for you and then expands on that protocol with the WebSocket class - pretty easy tbf.

EDIT1:
(I think Netty itself did introduce a HttpHandler - unsure whether or not DotNetty introduced this as well)

EDIT2:
Well technically speaking, Air can still be used as a client for players to use (no its not in-browser or on mobile) but it does the job - aaaaaand you can pretty much recompile it out-of-the-box. :)

Unsure how you've used it, but its goal is to be 1:1 with netty.

It's had HTTP codecs for a few years now and provides a far greater level of abstraction. Until you mention specific cases where .NET would be better I don't see a reason to re-invent the wheel.

Nitro does have some quirks I've noticed but nothings perfect, we've opened GB issues for the ones we care about. We have no desire to support the air client right now.

April 19th (this morning)
  • Fixed a bunch of issues with walking, avoiding redundant recalcs
  • Added exception handler for task worker, separate thread.
  • Added cancellation tokens to a few things on shutdown / dispose

Getting ready to merge into main for 0.8 tag, also been focusing on the CMS & API so rate of progress has declined temporarily while we finalize the 0.9 board & get any open prs merged.
 
Last edited:

dominic

Active Member
Dec 16, 2011
175
84
Unsure how you've used it, but its goal is to be 1:1 with netty.

It's had HTTP codecs for a few years now and provides a far greater level of abstraction. Until you mention specific cases where .NET would be better I don't see a reason to re-invent the wheel.

Nitro does have some quirks I've noticed but nothings perfect, we've opened GB issues for the ones we care about. We have no desire to support the air client right now.

April 19th (this morning)
  • Fixed a bunch of issues with walking, avoiding redundant recalcs
  • Added exception handler for task worker, separate thread.
  • Added cancellation tokens to a few things on shutdown / dispose

Getting ready to merge into main for 0.8 tag, also been focusing on the CMS & API so rate of progress has declined temporarily while we finalize the 0.9 board & get any open prs merged.
DotNetty is literally re-inventing the wheel nowadays, since WS is natively supported by MS.

(what is GB?)

Nitro doesn't just have quirks, I think @TheGeneral mentioned that the way it processes incoming packets are incorrect, hence why you cannot just switch been Nitro and Air without hassle.

I strongly advice you to look into Air, before building it around Nitro ending up with a bunch of incomplete stubs.

Would love to see some code examples, looks like you're doing great.
 

habtard

Member
Jan 30, 2020
32
30
DotNetty is literally re-inventing the wheel nowadays, since WS is natively supported by MS.

(what is GB?)

Nitro doesn't just have quirks, I think @TheGeneral mentioned that the way it processes incoming packets are incorrect, hence why you cannot just switch been Nitro and Air without hassle.

I strongly advice you to look into Air, before building it around Nitro ending up with a bunch of incomplete stubs.

Would love to see some code examples, looks like you're doing great.

I can't comment on the state of Nitro because I haven't studied the client enough, I just recall having to do some weird stuff on outgoing data for Nitro to understand it the same way flash was fine with it but this was over a year ago.

I have no desire to ever support Air, I think Nitro is great, why not work collaboratively towards improving it?

Also I meant GH, GitHub whoops...

Finally I wont spend time re-iterating over points I've already made. Dotnetty offers a very nice level of encapsulation that we're happy with for our specific use case. It brought our networking code down from 100's of lines to sub 100, and simplifies the task of adding additional communication layers to our application.

Updates
Closed a few PR's this morning, will merge dev into main this afternoon (250+ commits) for the 0.8 release. Will also release a planned work items list (0.9 board) when ready.

CMS (svelte) and API (go) is complete and live at , but I'll announce details on these in a separate thread and/or on the discord when I'm ready.
 

dominic

Active Member
Dec 16, 2011
175
84
I can't comment on the state of Nitro because I haven't studied the client enough, I just recall having to do some weird stuff on outgoing data for Nitro to understand it the same way flash was fine with it but this was over a year ago.

I have no desire to ever support Air, I think Nitro is great, why not work collaboratively towards improving it?

Also I meant GH, GitHub whoops...

Finally I wont spend time re-iterating over points I've already made. Dotnetty offers a very nice level of encapsulation that we're happy with for our specific use case. It brought our networking code down from 100's of lines to sub 100, and simplifies the task of adding additional communication layers to our application.

Updates
Closed a few PR's this morning, will merge dev into main this afternoon (250+ commits) for the 0.8 release. Will also release a planned work items list (0.9 board) when ready.

CMS (svelte) and API (go) is complete and live at , but I'll announce details on these in a separate thread and/or on the discord when I'm ready.
\> api in go
\> ws in dotnetty

\> doesnt like reinventing the wheel

well i wish you the best of luck not reinventing the wheel a third time. can't wait to see your progress though.
 

habtard

Member
Jan 30, 2020
32
30
\> api in go
\> ws in dotnetty

\> doesnt like reinventing the wheel

well i wish you the best of luck not reinventing the wheel a third time. can't wait to see your progress though.
You seem stupid, hence why I'm not investing much time into replying to you.

There aren't any web based projects that support Sadie, this would be the initial one hence the creation so people have something to work with.

Writing a web socket server with HttpListener isn't re-inventing the wheel but writing one in a popular security and unit tested networking library that encapsulates 90% of the logic is?
 
Last edited:

TheGeneral

Active Member
Dec 27, 2016
149
164
Nitro doesn't just have quirks, I think @TheGeneral mentioned that the way it processes incoming packets are incorrect, hence why you cannot just switch been Nitro and Air without hassle.

I strongly advice you to look into Air, before building it around Nitro ending up with a bunch of incomplete stubs.
Nitro has been build against shitty Arcturus as ground truth instead of the official Habbo servers. Mistakes in Arcturus result in issues in Nitro.
 

habtard

Member
Jan 30, 2020
32
30
April 20th
  • Finished player periodic currency reward system

You can now define periodic rewards of any type using the database.

You must be registered for see images attach


Code Snippet

You must be registered for see images attach


You must be registered for see images attach


Any rewards given are also logged in the periodic_currency_reward_logs table.

You can also toggle between two settings with this option in server_settings
You must be registered for see images attach


Enabled (Fair): Rewards will go off a players online time
Disabled (Unfair): Rewards fire on a fixed interval regardless of player online time.

Few other bits
  • Avatar data (motto and figure code) now saved live on change for instant website updates
  • Fixed an issue with dbContext in multi threaded scenarios,

Catch us at the !
Post automatically merged:

April 21st
  • Tons of refactoring, rewrote all of tile mapping
  • Added a few new unit tests ( related to tile mapping )
  • Refactored commands to list their required permissions
Commands
We've added a few basic commands (14 to be exact). Our plan with this is based on . Further customization / ability can be done via plugins.

You must be registered for see images attach


Few code snippets

You must be registered for see images attach

You must be registered for see images attach

Post automatically merged:

April 22nd
  • Refactored commands with further utility methods and options
  • Working on user walking collisions and over lapping
  • Added a server error writer for when the client sends an unknown header
  • Refactored room creation and loading

See here

You must be registered for see images attach


You must be registered for see images attach

Post automatically merged:

April 23rd
  • Added placement validation to furniture placements
  • Worked a lot on tile mapping and updating status re-actively
  • Optimized EF usage to be more optimal on record updates
  • Players now load their rooms on login to avoid re trips to the DB

You must be registered for see images attach

Post automatically merged:

April 24th
- Working on

You must be registered for see images attach


April 25th
  • Added accounts settings page to SadieCMS
  • Added staff page to SadieCMS
  • Added player profiles (/profile/[username]) to SadieCMS

April 26th
  • Working on the schema converter, about 80%
  • Packet writers are now serialized from their properties

You must be registered for see images attach

Post automatically merged:

Not really updating here anymore due to lack of interest but daily commits are still happening.
Checking discord for live updates.

Few highlights
  • Tons of refactoring
  • Furniture interaction updates
  • Event and packet serialization
Post automatically merged:

Plugin Support

Sadie now supports plugins for commands and furniture interactions.
Just make a class that inherits from the matching interface and you're done.

Test example
You must be registered for see images attach


You must be registered for see images attach


In the coming weeks I'll be improving this and providing a better API design, possibly opening it up to extra events but its a start.
Post automatically merged:

Ton of refactoring done, whole solutions now cleaner.

Room Bots
You can now view them in inventory

You must be registered for see images attach


I've also done a lot of refactoring to how room users work, a lot of logic is now shared but not mixed (critical difference). Previous emulators like Arcturus and Plus have merged these responsibilities incorrectly which opens the opportunity for further over engineering to create a "distinction".

Sadie decouples the shared logic and extends it through deriving from the shared 'movement' class, a bot is a bot and a user is a user, design choices are open for discussion at this point.

Here is an example:

You must be registered for see images attach

Post automatically merged:

Furniture Interactions
Can now purchase and use teleports (see discord for videos)

Also mood lights have been done

You must be registered for see images attach


Probably more but I don't update here much anymore.

See discord for live updates.
Post automatically merged:

OneWayGates (quality is shit cuz ffmpeg, I record in mkv).

You must be registered for see images attach

Post automatically merged:

Extended the interaction API a lot, you can now write interactors for OnMove, OnWalkOn and OnWalkOff.

You must be registered for see images attach
 

Attachments

  • 1718115957171.png
    1718115957171.png
    33.5 KB · Views: 37
  • 1718269255105.png
    1718269255105.png
    76.3 KB · Views: 43
Last edited:

React

Member
Sep 17, 2023
213
93
Joined the discord, Something different in the community once again. Rejuvenating hope in future-development, good luck!
 

habtard

Member
Jan 30, 2020
32
30
Latest updates:
Added doorbell and password access
Users can now trade with each other
Can now purchase and place room bots
Added furniture interactions
  • Dice
  • Dimmer
  • 1 way gates
  • Gates
  • Teleport
Can now place and save room ads
Lots of work on tile mapping
Fixed a few bugs with posture
Tons of refactoring to core code
Optimizations to queries
Lazy loading added for everything
 
Last edited:

Users who are viewing this thread

Top