Sorry but I have been busy studying... among other thingsYou might aswell close the thread, If your going to be so disactive
I wasn't aware any of the code was view able to the public? Unless you saw it for the short time I had a github up.I don't like it how you call components of your emulator libraries. It would indicated that they are easily exchangeable and could be used for other projects.
Your github repo returns a 404.
private void MyVoid(bool clearBefore = false)
{
if (clearBefore && _myDictionary.Count > 0)
{
_myDictionary.Clear();
}
}
- Storing position cords better (1 column split by ,) so 2,9,14.5 instead of 3 individual columns for x,y,z
- Reduced memory slightly by finding out what parts are using the most memory.
- Coded a few more packets.
- Created GameMapping (assigned to every room, accessible on a GetGameMapping() function
I have also took a different route to other emulators. Other emulators don't really extend their functionality beyond what is needed and what the developer might want to do. Most functions are set with extra parameters to extend its functionality and choose if certain parts of the functions are executed, such as:
Code:private void MyVoid(bool clearBefore = false) { if (clearBefore && _myDictionary.Count > 0) { _myDictionary.Clear(); } }
Small steps, but still progress.
About your mysql data int type thing, I never said it would increase performance, and I wasn't referring to item positioning like you probably thought I was (unsure).This isn't better at all. MySQL has an int data type for a reason. This is bad practice and doesn't improve performance or functionality at all.
What parts used the most memory and how did you reduce it?
What packets, and what did you do?
What does this do?
What's the purpose of this?
I'm not trying to sound rude, but the changes you have decided to share are either bad practice or don't give any information at all. Perhaps you could share a little more information about your changes?
Thanks bud.Looks good, glad to see you're back on this. Good luck with this and hope to see it released in the near future.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using Sahara.Base.Game.Players;
namespace Sahara.Base.Game.Prizes
{
internal sealed class PrizeManager
{
private readonly ConcurrentDictionary<int, Prize> _prizes;
private readonly ConcurrentDictionary<int, List<int>> _prizeLogs;
public PrizeManager()
{
_prizes = new ConcurrentDictionary<int, Prize>();
_prizeLogs = new ConcurrentDictionary<int, List<int>>();
LoadPrizes(false);
}
private void LoadPrizes(bool clearBefore)
{
if (clearBefore && _prizes.Count > 0)
{
_prizes.Clear();
}
using (var mysqlConnection = Sahara.GetServer().GetMySql().GetConnection())
{
mysqlConnection.OpenConnection();
mysqlConnection.SetQuery("SELECT * FROM `server_rewards` WHERE `enabled` = @enabled");
mysqlConnection.AddParameter("enabled", "1");
var dataTable = mysqlConnection.GetTable();
if (dataTable == null)
{
return;
}
foreach (DataRow prizeRow in dataTable.Rows)
{
_prizes.TryAdd(Convert.ToInt32(prizeRow["id"]), new Prize(Convert.ToInt32(prizeRow["id"]), Convert.ToInt32(prizeRow["reward_start"]), Convert.ToInt32(prizeRow["reward_end"]), Sahara.GetServer().GetUtility().GetPrizeTypeFromString(Convert.ToString(prizeRow["reward_type"])), Convert.ToString(prizeRow["reward_data"]), Convert.ToString(prizeRow["message"])));
}
mysqlConnection.CloseConnection();
}
}
public void CheckPrizes(Player player)
{
if (player?.GetPlayerData() == null)
{
return;
}
foreach (var prizeEntry in _prizes.Where(prizeEntry => !ReceivedPrize(player.GetPlayerData().PlayerId, prizeEntry.Key)).Where(prizeEntry => prizeEntry.Value.Ready()))
{
prizeEntry.Value.OnReceive(player);
}
}
public void LogReceivedPrize(int playerId, int prizeId)
{
if (!_prizeLogs.ContainsKey(playerId))
{
_prizeLogs.TryAdd(playerId, new List<int>());
}
if (!_prizeLogs[playerId].Contains(prizeId))
{
_prizeLogs[playerId].Add(prizeId);
}
using (var mysqlConnection = Sahara.GetServer().GetMySql().GetConnection())
{
mysqlConnection.OpenConnection();
mysqlConnection.SetQuery("INSERT INTO `server_reward_logs` VALUES (@playerId, @prizeId)");
mysqlConnection.AddParameter("playerId", playerId);
mysqlConnection.AddParameter("prizeId", prizeId);
mysqlConnection.RunQuery();
mysqlConnection.CloseConnection();
}
}
private bool ReceivedPrize(int playerId, int prizeId) => _prizeLogs.ContainsKey(playerId) && _prizeLogs[playerId].Contains(prizeId);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Sahara.Base.Game.Players;
using Sahara.Core.Net.Messages.Outgoing.Packets.Inventory.Purse;
namespace Sahara.Base.Game.Prizes
{
internal sealed class Prize : IPrize
{
private readonly int _prizeId;
private readonly int _prizeStart;
private readonly int _prizeEnd;
private readonly PrizeType _prizeType;
private readonly string _prizeData;
private readonly string _prizeMessage;
public Prize(int prizeId, int prizeStart, int prizeEnd, PrizeType prizeType, string prizeData, string prizeMessage)
{
_prizeId = prizeId;
_prizeStart = prizeStart;
_prizeEnd = prizeEnd;
_prizeType = prizeType;
_prizeData = prizeData;
_prizeMessage = prizeMessage;
}
public bool Ready()
{
var now = Sahara.GetServer().GetUtility().GetUnixNow();
return (now >= _prizeStart && now <= _prizeEnd);
}
public void OnReceive(Player player)
{
switch (_prizeType)
{
case PrizeType.None:
return;
case PrizeType.Badge:
if (!player.GetPlayerData().GetBadgeManagement().HasBadge(_prizeData))
{
player.GetPlayerData().GetBadgeManagement().GiveBadge(_prizeData, true);
}
break;
case PrizeType.Credits:
player.GetPlayerData().Credits += Convert.ToInt32(_prizeData);
player.SendMessage(new CreditBalanceMessageComposer(player.GetPlayerData().Credits));
break;
case PrizeType.Duckets:
player.GetPlayerData().Duckets += Convert.ToInt32(_prizeData);
player.SendMessage(new HabboActivityPointNotificationMessageComposer(player.GetPlayerData().Duckets, Convert.ToInt32(_prizeData)));
break;
case PrizeType.Diamonds:
player.GetPlayerData().Diamonds += Convert.ToInt32(_prizeData);
player.SendMessage(new HabboActivityPointNotificationMessageComposer(player.GetPlayerData().Diamonds, Convert.ToInt32(_prizeData)));
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Sahara.Base.Game.Prizes
{
internal enum PrizeType
{
Credits,
Badge,
Duckets,
Diamonds,
None,
}
}
Looks good, good luck and carry on bro. Glad you continued this projectThanks bud.
Coded the prize system, think its called Rewards on Plus/Azure? anyway.. I thought I would share the code for a change, as @LukeOx said, I don't really share much and explain things well so I'll try and keep you guys in the loop in the near future
Code:using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.Linq; using Sahara.Base.Game.Players; namespace Sahara.Base.Game.Prizes { internal sealed class PrizeManager { private readonly ConcurrentDictionary<int, Prize> _prizes; private readonly ConcurrentDictionary<int, List<int>> _prizeLogs; public PrizeManager() { _prizes = new ConcurrentDictionary<int, Prize>(); _prizeLogs = new ConcurrentDictionary<int, List<int>>(); LoadPrizes(false); } private void LoadPrizes(bool clearBefore) { if (clearBefore && _prizes.Count > 0) { _prizes.Clear(); } using (var mysqlConnection = Sahara.GetServer().GetMySql().GetConnection()) { mysqlConnection.OpenConnection(); mysqlConnection.SetQuery("SELECT * FROM `server_rewards` WHERE `enabled` = @enabled"); mysqlConnection.AddParameter("enabled", "1"); var dataTable = mysqlConnection.GetTable(); if (dataTable == null) { return; } foreach (DataRow prizeRow in dataTable.Rows) { _prizes.TryAdd(Convert.ToInt32(prizeRow["id"]), new Prize(Convert.ToInt32(prizeRow["id"]), Convert.ToInt32(prizeRow["reward_start"]), Convert.ToInt32(prizeRow["reward_end"]), Sahara.GetServer().GetUtility().GetPrizeTypeFromString(Convert.ToString(prizeRow["reward_type"])), Convert.ToString(prizeRow["reward_data"]), Convert.ToString(prizeRow["message"]))); } mysqlConnection.CloseConnection(); } } public void CheckPrizes(Player player) { if (player?.GetPlayerData() == null) { return; } foreach (var prizeEntry in _prizes.Where(prizeEntry => !ReceivedPrize(player.GetPlayerData().PlayerId, prizeEntry.Key)).Where(prizeEntry => prizeEntry.Value.Ready())) { prizeEntry.Value.OnReceive(player); } } public void LogReceivedPrize(int playerId, int prizeId) { if (!_prizeLogs.ContainsKey(playerId)) { _prizeLogs.TryAdd(playerId, new List<int>()); } if (!_prizeLogs[playerId].Contains(prizeId)) { _prizeLogs[playerId].Add(prizeId); } using (var mysqlConnection = Sahara.GetServer().GetMySql().GetConnection()) { mysqlConnection.OpenConnection(); mysqlConnection.SetQuery("INSERT INTO `server_reward_logs` VALUES (@playerId, @prizeId)"); mysqlConnection.AddParameter("playerId", playerId); mysqlConnection.AddParameter("prizeId", prizeId); mysqlConnection.RunQuery(); mysqlConnection.CloseConnection(); } } private bool ReceivedPrize(int playerId, int prizeId) => _prizeLogs.ContainsKey(playerId) && _prizeLogs[playerId].Contains(prizeId); } }
Code:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Sahara.Base.Game.Players; using Sahara.Core.Net.Messages.Outgoing.Packets.Inventory.Purse; namespace Sahara.Base.Game.Prizes { internal sealed class Prize : IPrize { private readonly int _prizeId; private readonly int _prizeStart; private readonly int _prizeEnd; private readonly PrizeType _prizeType; private readonly string _prizeData; private readonly string _prizeMessage; public Prize(int prizeId, int prizeStart, int prizeEnd, PrizeType prizeType, string prizeData, string prizeMessage) { _prizeId = prizeId; _prizeStart = prizeStart; _prizeEnd = prizeEnd; _prizeType = prizeType; _prizeData = prizeData; _prizeMessage = prizeMessage; } public bool Ready() { var now = Sahara.GetServer().GetUtility().GetUnixNow(); return (now >= _prizeStart && now <= _prizeEnd); } public void OnReceive(Player player) { switch (_prizeType) { case PrizeType.None: return; case PrizeType.Badge: if (!player.GetPlayerData().GetBadgeManagement().HasBadge(_prizeData)) { player.GetPlayerData().GetBadgeManagement().GiveBadge(_prizeData, true); } break; case PrizeType.Credits: player.GetPlayerData().Credits += Convert.ToInt32(_prizeData); player.SendMessage(new CreditBalanceMessageComposer(player.GetPlayerData().Credits)); break; case PrizeType.Duckets: player.GetPlayerData().Duckets += Convert.ToInt32(_prizeData); player.SendMessage(new HabboActivityPointNotificationMessageComposer(player.GetPlayerData().Duckets, Convert.ToInt32(_prizeData))); break; case PrizeType.Diamonds: player.GetPlayerData().Diamonds += Convert.ToInt32(_prizeData); player.SendMessage(new HabboActivityPointNotificationMessageComposer(player.GetPlayerData().Diamonds, Convert.ToInt32(_prizeData))); break; default: throw new ArgumentOutOfRangeException(); } } } }
Code:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Sahara.Base.Game.Prizes { internal enum PrizeType { Credits, Badge, Duckets, Diamonds, None, } }
Some work related to it has been completed such as the game map, although the structure and basics of pathfinder have been planned out, can't say its in a usable state at the moment.I got a question @Sage . Have you started working on the pathfinder?
Skickat från min FRD-L09 via Tapatalk
I got an idea, it's up to you though. I think that the pathfinder should be like DreamPathFinder where it calculates closest tile instead of doing nothing like comet and plus, if the path isn't walkable. ( If the path is blocked or something)Some work related to it has been completed such as the game map, although the structure and basics of pathfinder have been planned out, can't say its in a usable state at the moment.
Cool, thanks bud, and I sure will, good luck and carry on! [emoji14]I'll definitely add that in, maybe as a configuration option so its optional? Also, please PM me any other ideas you may have as I do like that idea
Updates (tonight): I'm going to try and get most of the AI stuff out of the way tonight, pets and bots. Coding a new AI manager that handles AI globally across the whole emulator, not sure how Plus did it.
Windows is far from useless, anyway Mono Support will be implemented upon release.Make this available for Mono or Wine, because we need more emulators capable of running on Linux, so we dont have to go with useless Windows
Sent from my SM-G928F using Tapatalk