Seriosk
Programmer;
- Oct 29, 2016
- 256
- 105
Sirius was very well written in compartment to other emulators, but there were things I never really followed through with doing such as properly disposing of classes, initializing things correctly, and I never really had much experience in the MySQL driver for C# and how it worked.
In this new development, I will learn from my mistakes, write good quality code as I always do on public releases, and also keep you constantly updated with new code, screenshots, even gifs and other things. I kind of went quiet on my old development and worked behind the scenes and just posted updates when I felt like it.
If anyone wants a copy of Sirius (Completed) to improve, extend, or anything developer-based then you can inbox me, but I won't be publicly releasing it to just anyone, the role-play edition wasn't completed therefor I won't be releasing that either but feel free to message me if you're a developer looking to improve it or anything like that, the only people with a copy right now are myself and @JynX.
Main Focus
Write a clean, good quality emulator that comes with MySQL and MongoDB support, along with Mono support running on the latest PRODUCTION build of Habbo's client.
Anything Unique?
Along with scheduled database backups, support for MongoDB as well as MySQL, and a clean code base, there isn't much unique, but then there isn't usually anything unique about Habbo. I am sure I'll add unique features once the base has been completed and its in a production environment working well. An emulator can have millions of features, but them features don't matter if the base of the emulator is badly designed or badly written by a sloppy programmer who doesn't understand the language in-depth.
For the people who says I'll just give up on this
I finished Sirius, and I started a roleplay edition which admittedly I got bored with, but as you can see I am pretty motivated to my large projects that interest me, the roleplay version of Sirius didn't.
Have I used any of Sirius's code in this?
Well, the only thing I have kept the same (with minor edits) is the Configuration as it didn't really need rewriting, and it was pretty well coded. If you're a developer you'll understand that Configuration isn't really a large amount of code in Emulators, 70-80 lines if that.
Want to help?
I am actually looking for developers to help on this emulator, as I have previously said I want this emulator to be coded with good quality code, so if you're a kid that just codes basic commands please don't even ask. If you actually understand C# in-depth and know how to write key parts of emulators from scratch using clean code then send me a PM and I'll be sure to give you access to a repository with it on.
Awaiting List
- Configuration [100%]
- MongoDB [20%]
- MySQL [0%]
- Utilities [100%]
- Logging (NLog) [100%]
- Humanizer [100%]
- GameSockets [100%]
- Player Authentication [80%]
Library's / Packages used?
- Humanizer
- NLog
- MongoDB driver
- MySQL driver
Credits
- @JynX => Revision Updating
- Myself => Everything Else
Code Snippets?
Code:
namespace Hariak_Emulator.Emulator.Core.Config
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NLog;
using Utilities;
internal sealed class ConfigManager : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
private Dictionary<string, string> _configItems;
private string _configFile;
internal ConfigManager(string configFile)
{
_configItems = new Dictionary<string, string>();
_configFile = configFile;
}
internal void LoadConfig()
{
try
{
if (!File.Exists(_configFile) || Utilities.IsFileLocked(new FileInfo(_configFile)))
{
Logger.Error("Either your config file couldn't be found, or its open somewhere else.");
Console.ReadKey(true);
Environment.Exit(0);
}
_configItems = File.ReadLines(_configFile).Where(IsConfigurationLine).Select(line => line.Split('=')).ToDictionary(line => line[0], line => line[1]);
}
catch (Exception exception)
{
Logger.Fatal("Error while loading config: " + exception.Message);
Logger.Fatal(exception.StackTrace);
Console.ReadKey(true);
Environment.Exit(0);
}
}
private static bool IsConfigurationLine(string line)
{
return !line.StartsWith("#") && line.Contains("=");
}
internal string GetConfigValueByKey(string key)
{
string value;
if (!_configItems.TryGetValue(key, out value))
{
Logger.Warn("Missing configuration key `" + key + "`");
}
return value;
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
_configItems.Clear();
_configItems = null;
_configFile = "";
}
}
}
Code:
namespace Hariak_Emulator.Emulator.Core.Database
{
using System;
using MongoDB.Bson;
using MongoDB.Driver;
using NLog;
internal sealed class DatabaseManager
{
private readonly MongoClient _mongoClient;
private readonly IMongoDatabase _mongoDatabase;
internal DatabaseManager()
{
var databaseHostName = Hariak.HariakServer.Config.GetConfigValueByKey("database.mongodb.hostname");
var databasePort = Hariak.HariakServer.Config.GetConfigValueByKey("database.mongodb.port");
var databaseName = Hariak.HariakServer.Config.GetConfigValueByKey("database.mongodb.name");
_mongoClient = new MongoClient("mongodb://" + databaseHostName + ":" + databasePort);
_mongoDatabase = _mongoClient.GetDatabase(databaseName);
}
}
}
Code:
namespace Hariak_Emulator.Emulator.Core.Network.GameSockets
{
using System;
using System.Net;
using System.Net.Sockets;
using Base.Game.Habbo.Players.Players;
using NLog;
internal sealed class GameSocketManager : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
private readonly Socket _gameSocket;
internal GameSocketManager()
{
_gameSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
internal void Start()
{
var gameSocketPort = Convert.ToInt32(Hariak.HariakServer.Config.GetConfigValueByKey("game.socket.port"));
var gameSocketBacklog = Convert.ToInt32(Hariak.HariakServer.Config.GetConfigValueByKey("game.socket.backlog"));
_gameSocket.Bind(new IPEndPoint(IPAddress.Any, gameSocketPort));
_gameSocket.Listen(gameSocketBacklog);
_gameSocket.BeginAccept(OnAcceptConnection, _gameSocket);
}
private void OnAcceptConnection(IAsyncResult asyncResult)
{
try
{
if (_gameSocket == null)
{
return;
}
var server = (Socket)asyncResult.AsyncState;
var client = server.EndAccept(asyncResult);
var newPlayer = new Player(client);
if (!Hariak.HariakServer.GameManager.PlayerManager.TryAddPlayer(newPlayer))
{
Logger.Error("Failed to register new player on " + client.RemoteEndPoint);
}
Logger.Info("Registered a new player to the server.");
}
catch (SocketException socketException)
{
Logger.Fatal("Failed to accept socket connection: " + socketException.Message);
Logger.Fatal(socketException);
}
finally
{
_gameSocket?.BeginAccept(OnAcceptConnection, _gameSocket);
}
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
if (_gameSocket == null)
{
return;
}
_gameSocket.Shutdown(SocketShutdown.Both);
_gameSocket.Close();
_gameSocket.Dispose();
}
}
}
Code:
namespace Hariak_Emulator
{
using System;
using System.Diagnostics;
using Emulator.Base.Game;
using Emulator.Core.Config;
using Emulator.Core.Database;
using Emulator.Core.Network.GameSockets;
using Emulator.Core.Server;
using NLog;
internal sealed class HariakServer : IDisposable
{
private static readonly ILogger Logger = LogManager.GetCurrentClassLogger();
internal void Load()
{
try
{
Logger.Trace("Loading Emulator...");
var stopwatch = Stopwatch.StartNew();
var configStopwatch = Stopwatch.StartNew();
Config = new ConfigManager("assets/config/hariak_config.ini");
Config.LoadConfig();
configStopwatch.Stop();
Logger.Trace("Loaded Configuration [took " + configStopwatch.ElapsedMilliseconds + "ms]");
var databaseStopwatch = Stopwatch.StartNew();
Database = new DatabaseManager();
databaseStopwatch.Stop();
Logger.Trace("Loaded Database [took " + databaseStopwatch.ElapsedMilliseconds + "ms]");
var gameStopwatch = Stopwatch.StartNew();
GameManager = new GameManager();
gameStopwatch.Stop();
Logger.Trace("Loaded Game [took " + databaseStopwatch.ElapsedMilliseconds + "ms]");
var socketStopwatch = Stopwatch.StartNew();
GameSocketManagement = new GameSocketManager();
GameSocketManagement.Start();
socketStopwatch.Stop();
Logger.Trace("Loaded Game Sockets [took " + socketStopwatch.ElapsedMilliseconds + "ms]");
var workerStopwatch = Stopwatch.StartNew();
ServerWorker = new ServerWorker();
ServerWorker.StartWorker();
workerStopwatch.Stop();
Logger.Trace("Loaded Server Worker [took " + workerStopwatch.ElapsedMilliseconds + "ms]");
DateTimeStarted = DateTime.Now;
stopwatch.Stop();
Logger.Debug("Emulator has loaded [took " + stopwatch.ElapsedMilliseconds + "ms]");
Console.WriteLine();
}
catch (Exception exception)
{
Logger.Fatal("Error during startup: " + exception.Message);
Logger.Fatal(exception);
throw;
}
}
public ConfigManager Config { get; private set; }
public DatabaseManager Database { get; set; }
public GameManager GameManager { get; private set; }
public GameSocketManager GameSocketManagement { get; set; }
public ServerWorker ServerWorker { get; private set; }
public DateTime DateTimeStarted { get; private set; }
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
Config.Dispose();
GameSocketManagement.Dispose();
ServerWorker.Dispose();
}
}
}
Screenshots? (Just some random screenies, took them for personal use really)
Configuration File layout? basic INI...
Code:
# Database [mongoDB] configuration
database.mongodb.hostname=localhost
database.mongodb.port=27017
database.mongodb.name=hariak
# GameSocket configuration
game.socket.port=30000
game.socket.backlog=500[/FONT]
GitHub repo?
You must be registered for see links
Thank you, let's create a great emulator!
Last edited: