Compare commits
No commits in common. "no_db" and "main" have entirely different histories.
|
@ -0,0 +1,33 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Achievements;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Achievement;
|
||||
|
||||
public class RequestAchievementsMessageEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IAchievementManager _achievementManager;
|
||||
|
||||
public RequestAchievementsMessageEvent(IGameSessionManager gameSessionManager, IAchievementManager achievementManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_achievementManager = achievementManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.AchievementList;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new AchievementsScoreComposer(gameSession.Habbo.AchievementScore));
|
||||
await gameSession.SendComposerAsync(new AchievementsComposer(_achievementManager.Achievements.Values,
|
||||
gameSession.Habbo));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Catalog;
|
||||
|
||||
public class GetCatalogIndexEvent : IMessageEvent
|
||||
{
|
||||
private readonly ICatalogueManager _catalogueManager;
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public GetCatalogIndexEvent(ICatalogueManager catalogueManager, IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_catalogueManager = catalogueManager;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.GetCatalogIndex;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var mode = request.ReadString();
|
||||
|
||||
var categories =
|
||||
_catalogueManager.Pages.Values.Where(
|
||||
p => p.Parent is null && p.Modes.Contains(mode.ToLower()) && p.MinRank <= gameSession.Habbo.Rank);
|
||||
|
||||
await gameSession.SendComposerAsync(new CatalogPagesListComposer(categories, mode));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Catalog;
|
||||
|
||||
public class GetCatalogPageEvent : IMessageEvent
|
||||
{
|
||||
private readonly ICatalogueManager _catalogueManager;
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public GetCatalogPageEvent(ICatalogueManager catalogueManager, IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_catalogueManager = catalogueManager;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.GetCatalogPage;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var pageId = request.ReadInt32();
|
||||
var offerId = request.ReadInt32();
|
||||
var mode = request.ReadString();
|
||||
|
||||
if (!_catalogueManager.Pages.TryGetValue(pageId, out var page) || !page.Enabled ||
|
||||
page.MinRank > gameSession.Habbo.Rank || !page.Modes.Contains(mode.ToLower()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var featuredPages = page.Layout.Equals("frontpage4")
|
||||
? _catalogueManager.FeaturedPages.Values
|
||||
: new List<CatalogueFeaturedPage>();
|
||||
|
||||
await gameSession.SendComposerAsync(new CatalogPageMessageComposer(page, offerId, mode, featuredPages));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Catalog;
|
||||
|
||||
public class GetClubOffersMessageEvent : IMessageEvent
|
||||
{
|
||||
private readonly ICatalogueManager _catalogueManager;
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public GetClubOffersMessageEvent(ICatalogueManager catalogueManager, IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_catalogueManager = catalogueManager;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.GetClubOffers;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var currentSubscription = gameSession.Habbo.GetActiveSubscription();
|
||||
|
||||
await gameSession.SendComposerAsync(new HabboClubOffersMessageComposer(
|
||||
_catalogueManager.ClubOffers.Values.Where(co =>
|
||||
co.DiscountExtension == currentSubscription is
|
||||
{
|
||||
MonthsLeft: 0, DaysInMonthLeft: <= 5 and > 0
|
||||
}).ToList(), currentSubscription));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Catalog;
|
||||
|
||||
public class PurchaseFromCatalogEvent : IMessageEvent
|
||||
{
|
||||
private readonly ICatalogueManager _catalogueManager;
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public PurchaseFromCatalogEvent(ICatalogueManager catalogueManager, IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_catalogueManager = catalogueManager;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.CatalogPurchase;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var pageId = request.ReadInt32();
|
||||
var offerId = request.ReadInt32();
|
||||
var extraData = request.ReadString();
|
||||
var amount = request.ReadInt32();
|
||||
|
||||
if (amount < 0 || !_catalogueManager.Pages.TryGetValue(pageId, out var page))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (page.Layout.Equals("vip_buy"))
|
||||
{
|
||||
await _catalogueManager.PurchaseClubOffer(offerId, gameSession);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,12 @@ public class InfoRetrieveMessageEvent : IMessageEvent
|
|||
public IncomingHeaders Header => IncomingHeaders.UserInfo;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
await gameSession.SendComposerAsync(new UserInfoComposer());
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new UserInfoComposer(gameSession.Habbo));
|
||||
}
|
||||
}
|
|
@ -3,6 +3,9 @@ using Tiger.Communication.Messages.Interfaces;
|
|||
using Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
using Tiger.Communication.Messages.Outgoing.Security;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Game.Settings;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
|
@ -10,11 +13,49 @@ namespace Tiger.Communication.Messages.Incoming.Handshake;
|
|||
|
||||
public class SsoTicketMessageEvent : IMessageEvent
|
||||
{
|
||||
private readonly IRepository<Habbo> _habboRepository;
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly ISettingManager _settingManager;
|
||||
private readonly ILogger<SsoTicketMessageEvent> _logger;
|
||||
private readonly IAchievementManager _achievementManager;
|
||||
|
||||
public SsoTicketMessageEvent(IRepository<Habbo> habboRepository, IGameSessionManager gameSessionManager, ISettingManager settingManager, ILogger<SsoTicketMessageEvent> logger, IAchievementManager achievementManager)
|
||||
{
|
||||
_habboRepository = habboRepository;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_settingManager = settingManager;
|
||||
_logger = logger;
|
||||
_achievementManager = achievementManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.SecurityTicket;
|
||||
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
var habbo = await _habboRepository.FindOneByAsync(h => h.SsoTicket == request.ReadString());
|
||||
|
||||
if (habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("User not found", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
gameSession.Habbo = habbo;
|
||||
gameSession.Habbo.LastLogin = DateTime.Now;
|
||||
gameSession.Habbo.Online = true;
|
||||
_habboRepository.SaveAsync(gameSession.Habbo);
|
||||
|
||||
if (DateTime.Now.Hour == 15)
|
||||
{
|
||||
_achievementManager.UpdateAchievementAsync("ACH_HappyHour", 1, gameSession);
|
||||
}
|
||||
|
||||
_logger.LogInformation("{User} logged in", gameSession.Habbo.Username);
|
||||
|
||||
await gameSession.SendComposerAsync(new AuthenticatedComposer());
|
||||
await gameSession.SendComposerAsync(new HabboBroadcastMessageComposer("Beep goes the jeep"));
|
||||
await gameSession.SendComposerAsync(new HabboBroadcastMessageComposer(
|
||||
_settingManager.GetSetting<string>("welcome.message")
|
||||
.Replace("{user}", gameSession.Habbo.Username)
|
||||
));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Badges;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Inventory.Badges;
|
||||
|
||||
public class RequestBadgesEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public RequestBadgesEvent(IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserBadges;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new BadgesComposer(gameSession.Habbo.Badges));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
using System.Collections.ObjectModel;
|
||||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Inventory.Badges;
|
||||
|
||||
public class SetActivatedBadgesEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IRepository<Badge> _badgeRepository;
|
||||
|
||||
public SetActivatedBadgesEvent(IGameSessionManager gameSessionManager, IRepository<Badge> badgeRepository)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_badgeRepository = badgeRepository;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserBadgesCurrentUpdate;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var wearingBadges = new Collection<Badge>();
|
||||
var badgesToUpdate = new Dictionary<int, Badge>();
|
||||
var current = gameSession.Habbo.Badges.Where(b => b.Slot != 0);
|
||||
foreach (var currentBadge in current)
|
||||
{
|
||||
currentBadge.Slot = 0;
|
||||
badgesToUpdate.Add(currentBadge.Id, currentBadge);
|
||||
}
|
||||
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var slotId = request.ReadInt32();
|
||||
var code = request.ReadString();
|
||||
|
||||
if (slotId is < 1 or > 5 || string.IsNullOrEmpty(code)) continue;
|
||||
|
||||
var badge = gameSession.Habbo.Badges.FirstOrDefault(b => b.Code == code);
|
||||
|
||||
if (badge == null) continue;
|
||||
|
||||
badge.Slot = slotId;
|
||||
wearingBadges.Add(badge);
|
||||
|
||||
badgesToUpdate.TryAdd(badge.Id, badge);
|
||||
}
|
||||
|
||||
await _badgeRepository.SaveManyAsync(badgesToUpdate.Values);
|
||||
await gameSession.SendComposerAsync(new UserCurrentBadgesComposer(gameSession.Habbo.Id, wearingBadges));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Currency;
|
||||
using Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Inventory.Currency;
|
||||
|
||||
public class UserCurrencyEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
|
||||
public UserCurrencyEvent(IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserCurrency;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new UserCreditsComposer(gameSession.Habbo.Credits));
|
||||
await gameSession.SendComposerAsync(new UserCurrencyComposer(gameSession.Habbo.Activitypoints.Values));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Subscription;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Inventory.Subscription;
|
||||
|
||||
public class UserSubscriptionEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IAchievementManager _achievementManager;
|
||||
|
||||
public UserSubscriptionEvent(IGameSessionManager gameSessionManager, IAchievementManager achievementManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_achievementManager = achievementManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserSubscription;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
_achievementManager.UpdateAchievementAsync("ACH_HC", ((gameSession.Habbo.GetPastSubscriptionDays() / 31)), gameSession);
|
||||
|
||||
await gameSession.SendComposerAsync(new UserSubscriptionComposer(gameSession.Habbo.GetActiveSubscription(),
|
||||
gameSession.Habbo.GetPastSubscriptionDays()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Landingview;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.LandingView;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Landingview;
|
||||
|
||||
public class GetPromoArticlesEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly ILandingViewManager _landingViewManager;
|
||||
|
||||
public GetPromoArticlesEvent(IGameSessionManager gameSessionManager, ILandingViewManager landingViewManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_landingViewManager = landingViewManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.GetPromoArticles;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new PromoArticlesMessageComposer(_landingViewManager.PromoArticles));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Rooms;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Navigator;
|
||||
|
||||
public class GetUserFlatCatsMessageEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IRoomManager _roomManager;
|
||||
|
||||
public GetUserFlatCatsMessageEvent(IRoomManager roomManager, IGameSessionManager gameSessionManager)
|
||||
{
|
||||
_roomManager = roomManager;
|
||||
_gameSessionManager = gameSessionManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.GetUserFlatCats;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new UserFlatCatsComposer(_roomManager.PrivateCategories.Values,
|
||||
gameSession.Habbo.Rank));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Navigator;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Navigator;
|
||||
|
||||
public class NavigatorInitEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly INavigatorManager _navigatorManager;
|
||||
|
||||
public NavigatorInitEvent(IGameSessionManager gameSessionManager, INavigatorManager navigatorManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_navigatorManager = navigatorManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.NavigatorInit;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
await gameSession.SendComposerAsync(new NavigatorMetadataComposer(_navigatorManager.NavigatorViews.Values));
|
||||
await gameSession.SendComposerAsync(new NavigatorCollapsedComposer());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing;
|
||||
using Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Navigator;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.Navigator;
|
||||
|
||||
public class NavigatorSearchEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly INavigatorManager _navigatorManager;
|
||||
|
||||
public NavigatorSearchEvent(IGameSessionManager gameSessionManager, INavigatorManager navigatorManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_navigatorManager = navigatorManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.NavigatorSearch;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_navigatorManager.NavigatorViews.TryGetValue(request.ReadString(), out var navigatorView)) return;
|
||||
var qry = request.ReadString();
|
||||
|
||||
var message = new ServerMessage((short)OutgoingHeaders.NavigatorSearch);
|
||||
message.AppendString(navigatorView.Code);
|
||||
message.AppendString(qry);
|
||||
await navigatorView.Compose(message, gameSession.Habbo, qry);
|
||||
await gameSession.SendMessageAsync(message);
|
||||
|
||||
// await gameSession.SendComposerAsync(new NavigatorSearchComposer(navigatorView, request.ReadString(), gameSession.Habbo));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.User.Data;
|
||||
|
||||
public class UserCurrentBadgesEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IRepository<Badge> _badgeRepository;
|
||||
|
||||
public UserCurrentBadgesEvent(IGameSessionManager gameSessionManager, IRepository<Badge> badgeRepository)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_badgeRepository = badgeRepository;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserBadgesCurrent;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var habboId = request.ReadInt32();
|
||||
|
||||
var badges = await _badgeRepository.FindByAsync(b => b.Habbo.Id == habboId && b.Slot > 0);
|
||||
await gameSession.SendComposerAsync(new UserCurrentBadgesComposer(habboId, badges.ToList()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.Avatar;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Figuredata;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.User.Data;
|
||||
|
||||
public class UserFigureEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IFigureDataManager _figureDataManager;
|
||||
private readonly IRepository<Habbo> _habboRepository;
|
||||
private readonly IAchievementManager _achievementManager;
|
||||
|
||||
public UserFigureEvent(IGameSessionManager gameSessionManager, IFigureDataManager figureDataManager, IRepository<Habbo> habboRepository, IAchievementManager achievementManager)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_figureDataManager = figureDataManager;
|
||||
_habboRepository = habboRepository;
|
||||
_achievementManager = achievementManager;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserFigure;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
if (gameSession.Habbo == null)
|
||||
{
|
||||
await _gameSessionManager.CloseAsync("Not logged in", gameSession);
|
||||
return;
|
||||
}
|
||||
|
||||
var gender = request.ReadString().ToUpper();
|
||||
var figure = request.ReadString();
|
||||
|
||||
if ((gender != "M" && gender != "F") || (figure == gameSession.Habbo.Figure && gender == gameSession.Habbo.Gender.ToUpper()) /*||
|
||||
!_figureDataManager.ValidateFigure(figure, gender, gameSession.Habbo)*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gameSession.Habbo.Figure = figure;
|
||||
gameSession.Habbo.Gender = gender;
|
||||
_habboRepository.SaveAsync(gameSession.Habbo);
|
||||
|
||||
_achievementManager.UpdateAchievementAsync("ACH_AvatarLooks", 1, gameSession);
|
||||
|
||||
await gameSession.SendComposerAsync(new FigureUpdateComposer(figure, gender));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Communication.Messages.Incoming.User.Data;
|
||||
|
||||
public class UserProfileEvent : IMessageEvent
|
||||
{
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IRepository<Habbo> _habboRepository;
|
||||
|
||||
public UserProfileEvent(IGameSessionManager gameSessionManager, IRepository<Habbo> habboRepository)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_habboRepository = habboRepository;
|
||||
}
|
||||
|
||||
public IncomingHeaders Header => IncomingHeaders.UserProfile;
|
||||
public async Task HandleAsync(GameSession gameSession, ClientMessage request)
|
||||
{
|
||||
var habbo = await _habboRepository.FindAsync(request.ReadInt32());
|
||||
|
||||
if (habbo == null) return;
|
||||
|
||||
await gameSession.SendComposerAsync(new UserProfileComposer(habbo));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Avatar;
|
||||
|
||||
public class FigureUpdateComposer : IMessageComposer
|
||||
{
|
||||
private readonly string _figure;
|
||||
private readonly string _gender;
|
||||
|
||||
public FigureUpdateComposer(string figure, string gender)
|
||||
{
|
||||
_figure = figure;
|
||||
_gender = gender;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserFigure;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendString(_figure);
|
||||
message.AppendString(_gender);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
|
||||
public class CatalogPageMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly CataloguePage _page;
|
||||
private readonly int _offerId;
|
||||
private readonly string _mode;
|
||||
private readonly ICollection<CatalogueFeaturedPage> _featuredPages;
|
||||
|
||||
public CatalogPageMessageComposer(CataloguePage page, int offerId, string mode,
|
||||
ICollection<CatalogueFeaturedPage> featuredPages)
|
||||
{
|
||||
_page = page;
|
||||
_offerId = offerId;
|
||||
_mode = mode;
|
||||
_featuredPages = featuredPages;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.CatalogPage;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_page.Id);
|
||||
message.AppendString(_mode);
|
||||
message.AppendString(_page.Layout);
|
||||
message.AppendInt32(_page.Images.Count);
|
||||
|
||||
foreach (var image in _page.Images)
|
||||
{
|
||||
message.AppendString(image);
|
||||
}
|
||||
|
||||
message.AppendInt32(_page.Texts.Count);
|
||||
|
||||
foreach (var text in _page.Texts)
|
||||
{
|
||||
message.AppendString(text);
|
||||
}
|
||||
|
||||
message.AppendInt32(0);
|
||||
message.AppendInt32(_offerId);
|
||||
message.AppendBoolean(_page.SeasonalCurrency);
|
||||
message.AppendInt32(_featuredPages.Count);
|
||||
|
||||
foreach (var featuredPage in _featuredPages)
|
||||
{
|
||||
message.AppendInt32(featuredPage.SlotId);
|
||||
message.AppendString(featuredPage.Caption);
|
||||
message.AppendString(featuredPage.Image);
|
||||
message.AppendInt32((int)featuredPage.Type);
|
||||
switch (featuredPage.Type)
|
||||
{
|
||||
default:
|
||||
case CatalogueFeaturedPageType.PageName:
|
||||
case CatalogueFeaturedPageType.ProductName:
|
||||
message.AppendString(featuredPage.Data);
|
||||
break;
|
||||
case CatalogueFeaturedPageType.PageId:
|
||||
message.AppendInt32(int.TryParse(featuredPage.Data, out var pageId) ? pageId : -1);
|
||||
break;
|
||||
}
|
||||
message.AppendInt32((int)(DateTime.Now - featuredPage.Expire).TotalSeconds);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
|
||||
public class CatalogPagesListComposer : IMessageComposer
|
||||
{
|
||||
private readonly IEnumerable<CataloguePage> _pages;
|
||||
private readonly string _mode;
|
||||
|
||||
public CatalogPagesListComposer(IEnumerable<CataloguePage> pages, string mode)
|
||||
{
|
||||
_pages = pages;
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.CatalogPageList;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendBoolean(true);
|
||||
message.AppendInt32(0);
|
||||
message.AppendInt32(-1);
|
||||
message.AppendString("root");
|
||||
message.AppendString(string.Empty);
|
||||
message.AppendInt32(0);
|
||||
message.AppendInt32(_pages.Count());
|
||||
|
||||
foreach (var page in _pages)
|
||||
{
|
||||
SerializeNode(page, message);
|
||||
}
|
||||
|
||||
message.AppendBoolean(false);
|
||||
message.AppendString(_mode);
|
||||
}
|
||||
|
||||
private void SerializeNode(CataloguePage page, ServerMessage message)
|
||||
{
|
||||
message.AppendBoolean(page.Visible);
|
||||
message.AppendInt32(page.Icon);
|
||||
message.AppendInt32(page.Id);
|
||||
message.AppendString(page.InternalName);
|
||||
message.AppendString(page.Name);
|
||||
message.AppendInt32(0);
|
||||
message.AppendInt32(page.Children.Count);
|
||||
|
||||
foreach (var child in page.Children)
|
||||
{
|
||||
SerializeNode(child, message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
|
||||
public class HabboClubOffersMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<ClubOffer> _clubOffers;
|
||||
private readonly HabboSubscription? _habboSubscription;
|
||||
|
||||
public HabboClubOffersMessageComposer(ICollection<ClubOffer> clubOffers, HabboSubscription? habboSubscription)
|
||||
{
|
||||
_clubOffers = clubOffers;
|
||||
_habboSubscription = habboSubscription;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.ClubOffers;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_clubOffers.Count);
|
||||
|
||||
foreach (var clubOffer in _clubOffers)
|
||||
{
|
||||
var end = _habboSubscription is not null
|
||||
? _habboSubscription.Expires.AddDays(clubOffer.Days)
|
||||
: DateTime.Now.AddMonths(1);
|
||||
message.AppendInt32(clubOffer.Id);
|
||||
message.AppendString(clubOffer.Name);
|
||||
message.AppendBoolean(false); // does absolutely NOTHING
|
||||
message.AppendInt32(clubOffer.PriceCredits);
|
||||
message.AppendInt32(clubOffer.PriceActivitypoints);
|
||||
message.AppendInt32(clubOffer.ActivitypointsType);
|
||||
message.AppendBoolean(true); // always vip
|
||||
message.AppendInt32(0); // months
|
||||
message.AppendInt32(clubOffer.Days); // extra days
|
||||
message.AppendBoolean(true); // gift-able
|
||||
message.AppendInt32(0); // days left after purchase
|
||||
message.AppendInt32(end.Year);
|
||||
message.AppendInt32(end.Month);
|
||||
message.AppendInt32(end.Day);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
|
||||
public class NotEnoughBalanceMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly bool _notEnoughCredits;
|
||||
private readonly bool _notEnoughActivityPoints;
|
||||
private readonly int _activityPointsType;
|
||||
|
||||
public NotEnoughBalanceMessageComposer(bool notEnoughCredits, bool notEnoughActivityPoints, int activityPointsType)
|
||||
{
|
||||
_notEnoughCredits = notEnoughCredits;
|
||||
_notEnoughActivityPoints = notEnoughActivityPoints;
|
||||
_activityPointsType = activityPointsType;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.NotEnoughBalance;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendBoolean(_notEnoughCredits);
|
||||
message.AppendBoolean(_notEnoughActivityPoints);
|
||||
message.AppendInt32(_activityPointsType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Achievements;
|
||||
|
||||
public class AchievementComposer : IMessageComposer
|
||||
{
|
||||
private readonly Achievement _achievement;
|
||||
private readonly HabboAchievement _habboAchievement;
|
||||
|
||||
public AchievementComposer(Achievement achievement, HabboAchievement habboAchievement)
|
||||
{
|
||||
_achievement = achievement;
|
||||
_habboAchievement = habboAchievement;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.AchievementProgressed;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
var targetLevel = _habboAchievement.Level == _achievement.Levels.Count
|
||||
? _habboAchievement.Level
|
||||
: _habboAchievement.Level + 1;
|
||||
|
||||
message.AppendInt32(_achievement.Id);
|
||||
message.AppendInt32(targetLevel);
|
||||
message.AppendString($"{_achievement.Badge}{targetLevel}");
|
||||
message.AppendInt32(_habboAchievement.Progress);
|
||||
message.AppendInt32(_achievement.Levels[targetLevel].ProgressNeeded);
|
||||
message.AppendInt32(_achievement.Levels[targetLevel].RewardAmount);
|
||||
message.AppendInt32(_achievement.Levels[targetLevel].RewardType);
|
||||
message.AppendInt32(_habboAchievement.Progress);
|
||||
message.AppendBoolean(_habboAchievement.Level >= _achievement.Levels.Count);
|
||||
message.AppendString(_achievement.Category);
|
||||
message.AppendString(string.Empty);
|
||||
message.AppendInt32(_achievement.Levels.Count);
|
||||
message.AppendInt32(_habboAchievement.Level >= _achievement.Levels.Count ? 1 : 0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Achievements;
|
||||
|
||||
public class AchievementsComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<Achievement> _achievements;
|
||||
private readonly Habbo _habbo;
|
||||
|
||||
public AchievementsComposer(ICollection<Achievement> achievements, Habbo habbo)
|
||||
{
|
||||
_achievements = achievements;
|
||||
_habbo = habbo;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.AchievementList;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_achievements.Count);
|
||||
|
||||
foreach (var achievement in _achievements)
|
||||
{
|
||||
var targetLevel = 1;
|
||||
|
||||
if (_habbo.Achievements.TryGetValue(achievement.Id, out var habboAchievement))
|
||||
targetLevel = habboAchievement.Level == achievement.Levels.Count
|
||||
? habboAchievement.Level
|
||||
: habboAchievement.Level + 1;
|
||||
|
||||
message.AppendInt32(achievement.Id);
|
||||
message.AppendInt32(targetLevel);
|
||||
message.AppendString($"{achievement.Badge}{targetLevel}");
|
||||
message.AppendInt32(habboAchievement?.Progress ?? 0);
|
||||
message.AppendInt32(achievement.Levels[targetLevel].ProgressNeeded);
|
||||
message.AppendInt32(achievement.Levels[targetLevel].RewardAmount);
|
||||
message.AppendInt32(achievement.Levels[targetLevel].RewardType);
|
||||
message.AppendInt32(habboAchievement?.Progress ?? 0);
|
||||
message.AppendBoolean((habboAchievement?.Level ?? 0) >= achievement.Levels.Count);
|
||||
message.AppendString(achievement.Category);
|
||||
message.AppendString(string.Empty);
|
||||
message.AppendInt32(achievement.Levels.Count);
|
||||
message.AppendInt32((habboAchievement?.Level ?? 0) >= achievement.Levels.Count ? 1 : 0);
|
||||
}
|
||||
|
||||
message.AppendString(string.Empty);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Achievements;
|
||||
|
||||
public class AchievementsScoreComposer : IMessageComposer
|
||||
{
|
||||
private readonly int _score;
|
||||
|
||||
public AchievementsScoreComposer(int score)
|
||||
{
|
||||
_score = score;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserAchievementScore;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_score);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Badges;
|
||||
|
||||
public class BadgesComposer : IMessageComposer
|
||||
{
|
||||
private readonly IReadOnlyList<Badge> _badges;
|
||||
|
||||
public BadgesComposer(IEnumerable<Badge>? badges)
|
||||
{
|
||||
_badges = badges != null ? badges.ToList() : new List<Badge>();
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserBadges;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_badges.Count);
|
||||
|
||||
foreach (var badge in _badges)
|
||||
{
|
||||
message.AppendInt32(badge.Id);
|
||||
message.AppendString(badge.Code);
|
||||
}
|
||||
|
||||
var wearingBadges = _badges.Where(b => b.Slot > 0).ToList();
|
||||
|
||||
message.AppendInt32(wearingBadges.Count);
|
||||
|
||||
foreach (var wearingBadge in wearingBadges)
|
||||
{
|
||||
message.AppendInt32(wearingBadge.Slot);
|
||||
message.AppendString(wearingBadge.Code);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Currency;
|
||||
|
||||
public class UserCreditsComposer : IMessageComposer
|
||||
{
|
||||
private readonly int _credits;
|
||||
|
||||
public UserCreditsComposer(int credits)
|
||||
{
|
||||
_credits = credits;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserCredits;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendString($"{_credits}.0");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Currency;
|
||||
|
||||
public class UserCurrencyComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<Activitypoints> _activitypoints;
|
||||
|
||||
public UserCurrencyComposer(ICollection<Activitypoints> activitypoints)
|
||||
{
|
||||
_activitypoints = activitypoints;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserCurrency;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_activitypoints.Count);
|
||||
|
||||
foreach (var activitypoint in _activitypoints)
|
||||
{
|
||||
message.AppendInt32(activitypoint.Type);
|
||||
message.AppendInt32(activitypoint.Amount);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Inventory.Subscription;
|
||||
|
||||
public class UserSubscriptionComposer : IMessageComposer
|
||||
{
|
||||
private readonly HabboSubscription? _habboSubscription;
|
||||
private readonly int _pastSubscriptionDays;
|
||||
|
||||
public UserSubscriptionComposer(HabboSubscription? habboSubscription, int pastSubscriptionDays)
|
||||
{
|
||||
_habboSubscription = habboSubscription;
|
||||
_pastSubscriptionDays = pastSubscriptionDays;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserSubscription;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendString(_habboSubscription?.SubscriptionType ?? string.Empty);
|
||||
message.AppendInt32(_habboSubscription?.DaysInMonthLeft ?? 0);
|
||||
message.AppendInt32(_habboSubscription?.MonthsLeft ?? 0);
|
||||
message.AppendInt32(0); // periods subscribed ahead but why is this different than above?
|
||||
message.AppendInt32(0); // response type
|
||||
message.AppendBoolean(_pastSubscriptionDays > 0);
|
||||
message.AppendBoolean(true); // vip but always vip?
|
||||
message.AppendInt32(0); // past club days but is always vip so below is used
|
||||
message.AppendInt32(_pastSubscriptionDays);
|
||||
message.AppendInt32((int)(_habboSubscription?.MinutesLeft ?? 0));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.LandingView;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Landingview;
|
||||
|
||||
public class PromoArticlesMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<PromoArticle> _promoArticles;
|
||||
|
||||
public PromoArticlesMessageComposer(ICollection<PromoArticle> promoArticles)
|
||||
{
|
||||
_promoArticles = promoArticles;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.PromoArticles;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_promoArticles.Count);
|
||||
|
||||
foreach (var promoArticle in _promoArticles)
|
||||
{
|
||||
message.AppendInt32(promoArticle.Id);
|
||||
message.AppendString(promoArticle.Title);
|
||||
message.AppendString(promoArticle.BodyText);
|
||||
message.AppendString(promoArticle.ButtonText);
|
||||
message.AppendInt32((int)promoArticle.LinkType);
|
||||
message.AppendString(promoArticle.LinkContent);
|
||||
message.AppendString(promoArticle.ImageUrl);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
|
||||
public class NavigatorCollapsedComposer : IMessageComposer
|
||||
{
|
||||
public OutgoingHeaders Header => OutgoingHeaders.NavigatorCollapsed;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(1);
|
||||
message.AppendString("official");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Navigator.Views;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
|
||||
public class NavigatorMetadataComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<INavigatorView> _navigatorViews;
|
||||
|
||||
public NavigatorMetadataComposer(ICollection<INavigatorView> navigatorViews)
|
||||
{
|
||||
_navigatorViews = navigatorViews;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.NavigatorMetadata;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_navigatorViews.Count);
|
||||
|
||||
foreach (var navigatorView in _navigatorViews)
|
||||
{
|
||||
message.AppendString(navigatorView.Code);
|
||||
message.AppendInt32(0); // saved searches
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Game.Navigator.Views;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
|
||||
public class NavigatorSearchComposer : IMessageComposer
|
||||
{
|
||||
private readonly INavigatorView _navigatorView;
|
||||
private readonly string _query;
|
||||
private readonly Habbo _habbo;
|
||||
|
||||
public NavigatorSearchComposer(INavigatorView navigatorView, string query, Habbo habbo)
|
||||
{
|
||||
_navigatorView = navigatorView;
|
||||
_query = query;
|
||||
_habbo = habbo;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.NavigatorSearch;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendString(_navigatorView.Code);
|
||||
message.AppendString(_query);
|
||||
_navigatorView.Compose(message, _habbo, _query).Wait();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Rooms;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Navigator;
|
||||
|
||||
public class UserFlatCatsComposer : IMessageComposer
|
||||
{
|
||||
private readonly ICollection<RoomPrivateCategory> _privateCategories;
|
||||
private readonly int _rank;
|
||||
|
||||
public UserFlatCatsComposer(ICollection<RoomPrivateCategory> privateCategories, int rank)
|
||||
{
|
||||
_privateCategories = privateCategories;
|
||||
_rank = rank;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.NavigatorCategories;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_privateCategories.Count);
|
||||
|
||||
foreach (var privateCategory in _privateCategories)
|
||||
{
|
||||
message.AppendInt32(privateCategory.Id);
|
||||
message.AppendString(privateCategory.Name);
|
||||
message.AppendBoolean(privateCategory.MinRank <= _rank);
|
||||
message.AppendBoolean(true); // automatic?
|
||||
message.AppendString(""); // automatic category key?
|
||||
message.AppendString(""); // global category key?
|
||||
message.AppendBoolean(privateCategory.MinRank >= 4);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
|
||||
public class AchievementNotificationMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly HabboAchievement _habboAchievement;
|
||||
private readonly int _badgeId;
|
||||
|
||||
public AchievementNotificationMessageComposer(HabboAchievement habboAchievement, int badgeId)
|
||||
{
|
||||
_habboAchievement = habboAchievement;
|
||||
_badgeId = badgeId;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.AchievementNotification;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_habboAchievement.Achievement.Id);
|
||||
message.AppendInt32(_habboAchievement.Level);
|
||||
message.AppendInt32(_badgeId);
|
||||
message.AppendString($"{_habboAchievement.Achievement.Badge}{_habboAchievement.Level}");
|
||||
message.AppendInt32(0); // points?
|
||||
message.AppendInt32(_habboAchievement.Achievement.Levels[_habboAchievement.Level].RewardAmount);
|
||||
message.AppendInt32(_habboAchievement.Achievement.Levels[_habboAchievement.Level].RewardType);
|
||||
message.AppendInt32(_habboAchievement.Achievement.Levels[_habboAchievement.Level].Points);
|
||||
message.AppendInt32(_habboAchievement.Achievement.Id);
|
||||
message.AppendString(_habboAchievement.Level > 1 ? $"{_habboAchievement.Achievement.Badge}{_habboAchievement.Level - 1}" : string.Empty);
|
||||
message.AppendString(_habboAchievement.Achievement.Category);
|
||||
message.AppendBoolean(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
|
||||
public class ActivityPointNotificationMessageComposer : IMessageComposer
|
||||
{
|
||||
private readonly int _amount;
|
||||
private readonly int _amountChanged;
|
||||
private readonly int _type;
|
||||
|
||||
public ActivityPointNotificationMessageComposer(int amount, int amountChanged, int type)
|
||||
{
|
||||
_amount = amount;
|
||||
_amountChanged = amountChanged;
|
||||
_type = type;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.ActivityPointNotification;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_amount);
|
||||
message.AppendInt32(_amountChanged);
|
||||
message.AppendInt32(_type);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
|
||||
public class UserCurrentBadgesComposer : IMessageComposer
|
||||
{
|
||||
private readonly int _habboId;
|
||||
private readonly ICollection<Badge> _badges;
|
||||
|
||||
public UserCurrentBadgesComposer(int habboId, ICollection<Badge> badges)
|
||||
{
|
||||
_habboId = habboId;
|
||||
_badges = badges;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserBadgesCurrent;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_habboId);
|
||||
message.AppendInt32(_badges.Count);
|
||||
|
||||
foreach (var badge in _badges)
|
||||
{
|
||||
message.AppendInt32(badge.Slot);
|
||||
message.AppendString(badge.Code);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,26 +1,34 @@
|
|||
using System.Globalization;
|
||||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
|
||||
public class UserInfoComposer : IMessageComposer
|
||||
{
|
||||
private readonly Habbo _habbo;
|
||||
|
||||
public UserInfoComposer(Habbo habbo)
|
||||
{
|
||||
_habbo = habbo;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserInfo;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(1);
|
||||
message.AppendString("Test");
|
||||
message.AppendString("FIGURE");
|
||||
message.AppendString("M");
|
||||
message.AppendString("Hello World");
|
||||
message.AppendInt32(_habbo.Id);
|
||||
message.AppendString(_habbo.Username);
|
||||
message.AppendString(_habbo.Figure);
|
||||
message.AppendString(_habbo.Gender);
|
||||
message.AppendString(_habbo.Motto);
|
||||
message.AppendString(string.Empty);
|
||||
message.AppendBoolean(false);
|
||||
message.AppendInt32(0); // respect received
|
||||
message.AppendInt32(0); // respect points to give
|
||||
message.AppendInt32(0); // scratch to give
|
||||
message.AppendBoolean(false);
|
||||
message.AppendString(string.Empty);
|
||||
message.AppendString(_habbo.LastLogin?.ToString(CultureInfo.CurrentCulture) ?? string.Empty);
|
||||
message.AppendBoolean(false); // can change name
|
||||
message.AppendBoolean(false); // safety locked
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
using System.Globalization;
|
||||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Communication.Messages.Outgoing.User.Data;
|
||||
|
||||
public class UserProfileComposer : IMessageComposer
|
||||
{
|
||||
private readonly Habbo _habbo;
|
||||
|
||||
public UserProfileComposer(Habbo habbo)
|
||||
{
|
||||
_habbo = habbo;
|
||||
}
|
||||
|
||||
public OutgoingHeaders Header => OutgoingHeaders.UserProfile;
|
||||
public void Compose(ServerMessage message)
|
||||
{
|
||||
message.AppendInt32(_habbo.Id);
|
||||
message.AppendString(_habbo.Username);
|
||||
message.AppendString(_habbo.Figure);
|
||||
message.AppendString(_habbo.Motto);
|
||||
message.AppendString(_habbo.AccountCreated.ToString(CultureInfo.CurrentCulture));
|
||||
message.AppendInt32(_habbo.AchievementScore);
|
||||
message.AppendInt32(0); // friend count
|
||||
message.AppendBoolean(false); // is friend
|
||||
message.AppendBoolean(false); // friend request sent
|
||||
message.AppendBoolean(_habbo.Online);
|
||||
message.AppendInt32(0); // groups
|
||||
message.AppendInt32((int)(_habbo.LastLogin == null ? 0 : (DateTime.Now - _habbo.LastLogin.Value).TotalSeconds));
|
||||
message.AppendBoolean(true); // open but why would it not open?
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public class Achievement
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Badge { get; set; } = null!;
|
||||
public virtual string Category { get; set; } = null!;
|
||||
public virtual IDictionary<int, AchievementLevel> Levels { get; set; } = new Dictionary<int, AchievementLevel>();
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public class AchievementLevel
|
||||
{
|
||||
public virtual Achievement Achievement { get; set; } = null!;
|
||||
public virtual int Level { get; set; }
|
||||
public virtual int RewardAmount { get; set; }
|
||||
public virtual int RewardType { get; set; }
|
||||
public virtual int Points { get; set; }
|
||||
public virtual int ProgressNeeded { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not AchievementLevel other)
|
||||
return false;
|
||||
|
||||
return Achievement.Id == other.Achievement.Id && Level == other.Level;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hash = 17;
|
||||
hash = hash * 23 + Achievement.Id.GetHashCode();
|
||||
hash = hash * 23 + Level.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public class AchievementLevelMap : ClassMap<AchievementLevel>
|
||||
{
|
||||
public AchievementLevelMap()
|
||||
{
|
||||
Table("achievement_levels");
|
||||
LazyLoad();
|
||||
CompositeId()
|
||||
.KeyProperty(al => al.Level, "level")
|
||||
.KeyReference(al => al.Achievement, "achievement_id");
|
||||
Map(al => al.RewardAmount).Column("reward_amount").Not.Nullable();
|
||||
Map(al => al.RewardType).Column("reward_type").Not.Nullable();
|
||||
Map(al => al.ProgressNeeded).Column("progress_needed").Not.Nullable();
|
||||
Map(al => al.Points).Column("points").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Achievements;
|
||||
using Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public class AchievementManager : IAchievementManager
|
||||
{
|
||||
private readonly IRepository<Achievement> _achievementRepository;
|
||||
private readonly ILogger<IAchievementManager> _logger;
|
||||
private readonly IRepository<Badge> _badgesRepository;
|
||||
private readonly IRepository<Habbo> _habboRepository;
|
||||
|
||||
public AchievementManager(IRepository<Achievement> achievementRepository, ILogger<IAchievementManager> logger, IRepository<Badge> badgesRepository, IRepository<Habbo> habboRepository)
|
||||
{
|
||||
_achievementRepository = achievementRepository;
|
||||
_logger = logger;
|
||||
_badgesRepository = badgesRepository;
|
||||
_habboRepository = habboRepository;
|
||||
}
|
||||
|
||||
public IDictionary<string, Achievement> Achievements { get; private set; } = new Dictionary<string, Achievement>();
|
||||
|
||||
public async Task LoadAchievementsAsync()
|
||||
{
|
||||
Achievements = (await _achievementRepository.FindByAsync()).ToDictionary(a => a.Badge, a => a);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} Achievements", Achievements.Count);
|
||||
}
|
||||
|
||||
public async Task UpdateAchievementAsync(string achievementName, int progress, GameSession session)
|
||||
{
|
||||
if (session.Habbo is null) return;
|
||||
|
||||
if (!Achievements.TryGetValue(achievementName, out var achievement)) return;
|
||||
|
||||
if (progress == 0) return;
|
||||
|
||||
if (!session.Habbo.Achievements.TryGetValue(achievement.Id, out var habboAchievement))
|
||||
{
|
||||
habboAchievement = new HabboAchievement()
|
||||
{
|
||||
Level = 0,
|
||||
Progress = 0,
|
||||
Achievement = achievement,
|
||||
Habbo = session.Habbo
|
||||
};
|
||||
|
||||
session.Habbo.Achievements.Add(achievement.Id, habboAchievement);
|
||||
}
|
||||
|
||||
if (habboAchievement.Level == achievement.Levels.Count) return;
|
||||
|
||||
var targetLevel = habboAchievement.Level + 1;
|
||||
var achievementLevel = achievement.Levels[targetLevel];
|
||||
|
||||
habboAchievement.Progress += progress;
|
||||
|
||||
if (habboAchievement.Progress >= achievementLevel.ProgressNeeded)
|
||||
{
|
||||
habboAchievement.Level++;
|
||||
|
||||
Badge badge;
|
||||
|
||||
if (habboAchievement.Level == 1)
|
||||
{
|
||||
badge = new Badge
|
||||
{
|
||||
Habbo = session.Habbo,
|
||||
Code = $"{achievement.Badge}1"
|
||||
};
|
||||
session.Habbo.Badges.Add(badge);
|
||||
}
|
||||
else
|
||||
{
|
||||
var currentBadge =
|
||||
session.Habbo.Badges.SingleOrDefault(b =>
|
||||
b.Code == $"{achievement.Badge}{habboAchievement.Level - 1}");
|
||||
|
||||
if (currentBadge != null)
|
||||
{
|
||||
currentBadge.Code = $"{achievement.Badge}{habboAchievement.Level - 1}";
|
||||
badge = currentBadge;
|
||||
}
|
||||
else
|
||||
{
|
||||
badge = new Badge
|
||||
{
|
||||
Habbo = session.Habbo,
|
||||
Code = $"{achievement.Badge}1"
|
||||
};
|
||||
session.Habbo.Badges.Add(badge);
|
||||
}
|
||||
}
|
||||
|
||||
session.Habbo.AchievementScore += achievementLevel.Points;
|
||||
|
||||
if (achievementLevel.RewardAmount > 0)
|
||||
{
|
||||
session.Habbo.UpdateCurrency(achievementLevel.RewardType, achievementLevel.RewardAmount);
|
||||
session.SendComposerAsync(new ActivityPointNotificationMessageComposer(session.Habbo.Activitypoints[achievementLevel.RewardType].Amount, achievementLevel.RewardAmount, achievementLevel.RewardType));
|
||||
}
|
||||
|
||||
// session.CurrentRoom?.SendMessage(new UserChangeMessageComposer(session.RoomUser.VirtualId, session.User));
|
||||
|
||||
session.SendComposerAsync(new AchievementsScoreComposer(session.Habbo.AchievementScore));
|
||||
session.SendComposerAsync(new AchievementNotificationMessageComposer(habboAchievement, badge.Id));
|
||||
}
|
||||
|
||||
_habboRepository.SaveAsync(session.Habbo);
|
||||
|
||||
await session.SendComposerAsync(new AchievementComposer(achievement, habboAchievement));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public class AchievementMap : ClassMap<Achievement>
|
||||
{
|
||||
public AchievementMap()
|
||||
{
|
||||
Table("achievements");
|
||||
LazyLoad();
|
||||
Id(a => a.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(a => a.Badge).Column("badge").Not.Nullable();
|
||||
Map(a => a.Category).Column("category").Not.Nullable();
|
||||
HasMany(a => a.Levels).AsMap(al => al.Level).Cascade.All();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Game.Achievements;
|
||||
|
||||
public interface IAchievementManager
|
||||
{
|
||||
IDictionary<string, Achievement> Achievements { get; }
|
||||
Task LoadAchievementsAsync();
|
||||
Task UpdateAchievementAsync(string achievementName, int progress, GameSession session);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class CatalogueFeaturedPage
|
||||
{
|
||||
public virtual int SlotId { get; set; }
|
||||
public virtual string Image { get; set; } = null!;
|
||||
public virtual string Caption { get; set; } = null!;
|
||||
public virtual CatalogueFeaturedPageType Type { get; set; }
|
||||
public virtual DateTime Expire { get; set; }
|
||||
public virtual string Data { get; set; } = null!;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class CatalogueFeaturedPageMap : ClassMap<CatalogueFeaturedPage>
|
||||
{
|
||||
public CatalogueFeaturedPageMap()
|
||||
{
|
||||
Table("catalogue_featured_pages");
|
||||
Id(fp => fp.SlotId).Column("slot_id").GeneratedBy.Identity();
|
||||
Map(fp => fp.Image).Column("image").Not.Nullable();
|
||||
Map(fp => fp.Caption).Column("caption").Not.Nullable();
|
||||
Map(fp => fp.Type).CustomType<int>().Column("type").Not.Nullable();
|
||||
Map(fp => fp.Expire).Column("expire").Not.Nullable();
|
||||
Map(fp => fp.Data).Column("data").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public enum CatalogueFeaturedPageType
|
||||
{
|
||||
PageName,
|
||||
PageId,
|
||||
ProductName
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Communication.Messages.Outgoing.Catalog;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Currency;
|
||||
using Tiger.Communication.Messages.Outgoing.Inventory.Subscription;
|
||||
using Tiger.Communication.Messages.Outgoing.Notifications;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class CatalogueManager : ICatalogueManager
|
||||
{
|
||||
private readonly IRepository<CataloguePage> _pagesRepository;
|
||||
private readonly ILogger<ICatalogueManager> _logger;
|
||||
private readonly IRepository<CatalogueFeaturedPage> _featuredPagesRepository;
|
||||
private readonly IRepository<ClubOffer> _clubOfferRepository;
|
||||
private readonly IRepository<HabboSubscription> _habboSubscriptionRepository;
|
||||
private readonly IAchievementManager _achievementManager;
|
||||
|
||||
public IDictionary<int, CataloguePage> Pages { get; private set; }
|
||||
public IDictionary<int, CatalogueFeaturedPage> FeaturedPages { get; private set; }
|
||||
public IDictionary<int, ClubOffer> ClubOffers { get; private set; }
|
||||
|
||||
public CatalogueManager(IRepository<CataloguePage> pagesRepository, ILogger<ICatalogueManager> logger,
|
||||
IRepository<CatalogueFeaturedPage> featuredPagesRepository, IRepository<ClubOffer> clubOfferRepository,
|
||||
IRepository<HabboSubscription> habboSubscriptionRepository, IAchievementManager achievementManager)
|
||||
{
|
||||
_pagesRepository = pagesRepository;
|
||||
_logger = logger;
|
||||
_featuredPagesRepository = featuredPagesRepository;
|
||||
_clubOfferRepository = clubOfferRepository;
|
||||
_habboSubscriptionRepository = habboSubscriptionRepository;
|
||||
_achievementManager = achievementManager;
|
||||
Pages = new Dictionary<int, CataloguePage>();
|
||||
FeaturedPages = new Dictionary<int, CatalogueFeaturedPage>();
|
||||
ClubOffers = new Dictionary<int, ClubOffer>();
|
||||
}
|
||||
|
||||
public async Task LoadPagesAsync()
|
||||
{
|
||||
Pages = (await _pagesRepository.FindByAsync()).ToDictionary(p => p.Id, p => p);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} catalogue pages", Pages.Count);
|
||||
}
|
||||
|
||||
public async Task LoadFeaturedPagesAsync()
|
||||
{
|
||||
FeaturedPages = (await _featuredPagesRepository.FindByAsync())
|
||||
.ToDictionary(p => p.SlotId, p => p);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} catalogue featured pages", FeaturedPages.Count);
|
||||
}
|
||||
|
||||
public async Task LoadClubOffersAsync()
|
||||
{
|
||||
ClubOffers = (await _clubOfferRepository.FindByAsync())
|
||||
.ToDictionary(co => co.Id);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} club offers", ClubOffers.Count);
|
||||
}
|
||||
|
||||
public async Task PurchaseClubOffer(int offerId, GameSession gameSession)
|
||||
{
|
||||
if (!ClubOffers.TryGetValue(offerId, out var clubOffer) || gameSession.Habbo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var tooShortOnCoins = clubOffer.PriceCredits > 0 && clubOffer.PriceCredits > gameSession.Habbo.Credits;
|
||||
var tooShortOnActivityPoints = clubOffer.PriceActivitypoints > 0 && clubOffer.PriceActivitypoints >
|
||||
gameSession.Habbo.GetActivityPoints(clubOffer.ActivitypointsType);
|
||||
|
||||
if (tooShortOnCoins || tooShortOnActivityPoints)
|
||||
{
|
||||
await gameSession.SendComposerAsync(new NotEnoughBalanceMessageComposer(tooShortOnCoins,
|
||||
tooShortOnActivityPoints, clubOffer.ActivitypointsType));
|
||||
return;
|
||||
}
|
||||
|
||||
if (clubOffer.PriceCredits > 0)
|
||||
{
|
||||
gameSession.Habbo.Credits -= clubOffer.PriceCredits;
|
||||
gameSession.SendComposerAsync(new UserCreditsComposer(gameSession.Habbo.Credits));
|
||||
}
|
||||
|
||||
if (clubOffer.PriceActivitypoints > 0)
|
||||
{
|
||||
gameSession.Habbo.UpdateCurrency(clubOffer.ActivitypointsType, -clubOffer.PriceActivitypoints);
|
||||
gameSession.SendComposerAsync(new ActivityPointNotificationMessageComposer(
|
||||
gameSession.Habbo.GetActivityPoints(clubOffer.ActivitypointsType), -clubOffer.PriceActivitypoints,
|
||||
clubOffer.ActivitypointsType));
|
||||
}
|
||||
|
||||
var currentSubscription = gameSession.Habbo.GetActiveSubscription();
|
||||
|
||||
if (currentSubscription != null)
|
||||
{
|
||||
currentSubscription.Expires = currentSubscription.Expires.AddDays(clubOffer.Days);
|
||||
currentSubscription.Habbo.Credits -= clubOffer.PriceCredits;
|
||||
currentSubscription.Habbo.UpdateCurrency(clubOffer.ActivitypointsType, -clubOffer.PriceActivitypoints);
|
||||
_habboSubscriptionRepository.SaveAsync(currentSubscription);
|
||||
gameSession.SendComposerAsync(new UserSubscriptionComposer(currentSubscription,
|
||||
gameSession.Habbo.GetPastSubscriptionDays()));
|
||||
}
|
||||
else
|
||||
{
|
||||
var subscription = new HabboSubscription
|
||||
{
|
||||
Expires = DateTime.Now.AddDays(clubOffer.Days),
|
||||
SubscriptionType = "habbo_club",
|
||||
Started = DateTime.Now,
|
||||
Habbo = gameSession.Habbo
|
||||
};
|
||||
_habboSubscriptionRepository.SaveAsync(subscription);
|
||||
gameSession.SendComposerAsync(new UserSubscriptionComposer(subscription,
|
||||
gameSession.Habbo.GetPastSubscriptionDays()));
|
||||
_achievementManager.UpdateAchievementAsync("ACH_HC", 1, gameSession);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class CataloguePage
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; } = null!;
|
||||
public virtual string InternalName { get; set; } = null!;
|
||||
public virtual string Layout { get; set; } = null!;
|
||||
public virtual bool Visible { get; set; }
|
||||
public virtual bool Enabled { get; set; }
|
||||
public virtual int Icon { get; set; }
|
||||
public virtual int MinRank { get; set; }
|
||||
public virtual CataloguePage? Parent { get; set; }
|
||||
public virtual IList<CataloguePage> Children { get; set; } = new List<CataloguePage>();
|
||||
public virtual IList<string> Images { get; set; } = new List<string>();
|
||||
public virtual IList<string> Texts { get; set; } = new List<string>();
|
||||
public virtual bool SeasonalCurrency { get; set; }
|
||||
public virtual IList<string> Modes { get; set; } = new List<string>();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class CataloguePageMap : ClassMap<CataloguePage>
|
||||
{
|
||||
public CataloguePageMap()
|
||||
{
|
||||
Table("catalogue_pages");
|
||||
LazyLoad();
|
||||
Id(c => c.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(c => c.Name).Column("name").Not.Nullable();
|
||||
Map(c => c.InternalName).Column("internal_name").Not.Nullable();
|
||||
Map(c => c.Layout).Column("layout").Not.Nullable();
|
||||
Map(c => c.Visible).Column("visible").Not.Nullable();
|
||||
Map(c => c.Enabled).Column("enabled").Not.Nullable();
|
||||
Map(c => c.Icon).Column("icon").Not.Nullable();
|
||||
Map(c => c.MinRank).Column("min_rank").Not.Nullable();
|
||||
References(x => x.Parent).Column("parent_id").Nullable();
|
||||
HasMany(x => x.Children).KeyColumn("parent_id").Inverse().Cascade.AllDeleteOrphan();
|
||||
Map(c => c.Images).CustomType<StringListTypeConverter>();
|
||||
Map(c => c.Texts).CustomType<StringListTypeConverter>();
|
||||
Map(c => c.SeasonalCurrency).Column("seasonal_currency").Not.Nullable();
|
||||
Map(c => c.Modes).CustomType<StringListTypeConverter>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class ClubOffer
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; } = null!;
|
||||
public virtual int PriceCredits { get; set; }
|
||||
public virtual int PriceActivitypoints { get; set; }
|
||||
public virtual int ActivitypointsType { get; set; }
|
||||
public virtual int Days { get; set; }
|
||||
public virtual bool DiscountExtension { get; set; }
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public class ClubOfferMap : ClassMap<ClubOffer>
|
||||
{
|
||||
public ClubOfferMap()
|
||||
{
|
||||
Table("catalogue_club_offers");
|
||||
Id(co => co.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(co => co.Name).Column("name").Not.Nullable();
|
||||
Map(co => co.PriceCredits).Column("price_credits").Not.Nullable();
|
||||
Map(co => co.PriceActivitypoints).Column("price_activitypoints").Not.Nullable();
|
||||
Map(co => co.ActivitypointsType).Column("activitypoints_type").Not.Nullable();
|
||||
Map(co => co.Days).Column("days").Not.Nullable();
|
||||
Map(co => co.DiscountExtension).Column("discount_extension").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Tiger.Networking.Game.Sessions;
|
||||
|
||||
namespace Tiger.Game.Catalogue;
|
||||
|
||||
public interface ICatalogueManager
|
||||
{
|
||||
public IDictionary<int, CataloguePage> Pages { get; }
|
||||
public IDictionary<int, CatalogueFeaturedPage> FeaturedPages { get; }
|
||||
public IDictionary<int, ClubOffer> ClubOffers { get; }
|
||||
Task LoadPagesAsync();
|
||||
Task LoadFeaturedPagesAsync();
|
||||
Task LoadClubOffersAsync();
|
||||
Task PurchaseClubOffer(int offerId, GameSession gameSession);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class Color
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Index { get; set; }
|
||||
public int Club { get; set; }
|
||||
public bool Selectable { get; set; }
|
||||
public string HexCode { get; set; } = null!;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class Figuredata
|
||||
{
|
||||
public List<Palette> Palettes { get; set; } = new();
|
||||
public List<SetType> SetTypes { get; set; } = new();
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using Newtonsoft.Json;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class FiguredataManager : IFigureDataManager
|
||||
{
|
||||
private readonly Figuredata? _figuredata;
|
||||
|
||||
public FiguredataManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
_figuredata = JsonConvert.DeserializeObject<Figuredata>(File.ReadAllText("FigureData.json"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateFigure(string newFigure, string newGender, Habbo habbo)
|
||||
{
|
||||
if (_figuredata is null)
|
||||
return false;
|
||||
|
||||
var parts = newFigure.Split('.');
|
||||
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (!part.Contains('-'))
|
||||
return false;
|
||||
|
||||
var subParts = part.Split('-');
|
||||
var setType = _figuredata.SetTypes.SingleOrDefault(st => st.Type == subParts[0]);
|
||||
|
||||
if (setType is null)
|
||||
return false;
|
||||
|
||||
var palette = _figuredata.Palettes.SingleOrDefault(p => p.Id == setType.PaletteId);
|
||||
|
||||
if (palette is null)
|
||||
return false;
|
||||
|
||||
var set = setType.Sets.SingleOrDefault(s => s.Id == int.Parse(subParts.Length >= 2 ? subParts[1] : "-1"));
|
||||
|
||||
if (set is null)
|
||||
return false;
|
||||
|
||||
// TODO: Check if is club
|
||||
// TODO: Check for buyable clothes
|
||||
|
||||
if (set.Gender.ToUpper() != newGender)
|
||||
return false;
|
||||
|
||||
if (set.Colorable && subParts.Length < 3)
|
||||
return false;
|
||||
|
||||
if (!set.Colorable) continue;
|
||||
|
||||
var paletteColor1 = palette.Colors.SingleOrDefault(c => c.Id == int.Parse(subParts[2]));
|
||||
|
||||
if (paletteColor1 is null)
|
||||
return false;
|
||||
|
||||
if (subParts.Length == 3) continue;
|
||||
|
||||
var paletteColor2 = palette.Colors.SingleOrDefault(c => c.Id == int.Parse(subParts[3]));
|
||||
|
||||
if (paletteColor2 is null)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public interface IFigureDataManager
|
||||
{
|
||||
bool ValidateFigure(string newFigure, string newGender, Habbo habbo);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class Palette
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public List<Color> Colors { get; set; } = new();
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class Part
|
||||
{
|
||||
public bool Colorable { get; set; }
|
||||
public int ColorIndex { get; set; }
|
||||
public uint Id { get; set; }
|
||||
public int Index { get; set; }
|
||||
public string Type { get; set; } = null!;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class Set
|
||||
{
|
||||
public int Club { get; set; }
|
||||
public bool Colorable { get; set; }
|
||||
public string Gender { get; set; } = null!;
|
||||
public int Id { get; set; }
|
||||
public bool Preselectable { get; set; }
|
||||
public bool Selectable { get; set; }
|
||||
public bool Sellable { get; set; }
|
||||
public List<Part> Parts { get; set; } = new();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
using System.Text.Json.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Tiger.Game.Figuredata;
|
||||
|
||||
public class SetType
|
||||
{
|
||||
public string Type { get; set; } = null!;
|
||||
[JsonProperty("mandatory_f_0")]
|
||||
public bool MandatoryF0 { get; set; }
|
||||
[JsonProperty("mandatory_f_1")]
|
||||
public bool MandatoryF1 { get; set; }
|
||||
[JsonProperty("mandatory_m_0")]
|
||||
public bool MandatoryM0 { get; set; }
|
||||
[JsonProperty("mandatory_m_1")]
|
||||
public bool MandatoryM1 { get; set; }
|
||||
public int PaletteId { get; set; }
|
||||
public List<Set> Sets { get; set; } = new();
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class Activitypoints
|
||||
{
|
||||
public virtual Habbo Habbo { get; set; } = null!;
|
||||
public virtual int Type { get; set; }
|
||||
public virtual int Amount { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not Activitypoints other)
|
||||
return false;
|
||||
|
||||
return Habbo.Id == other.Habbo.Id && Type == other.Type;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hash = 17;
|
||||
hash = hash * 23 + Habbo.Id.GetHashCode();
|
||||
hash = hash * 23 + Type.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class ActivitypointsMap : ClassMap<Activitypoints>
|
||||
{
|
||||
public ActivitypointsMap()
|
||||
{
|
||||
Table("habbo_activitypoints");
|
||||
LazyLoad();
|
||||
CompositeId()
|
||||
.KeyProperty(h => h.Type, "type")
|
||||
.KeyReference(h => h.Habbo, "habbo_id");
|
||||
Map(h => h.Amount).Column("amount").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class Badge
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual Habbo Habbo { get; set; } = null!;
|
||||
public virtual string Code { get; set; } = null!;
|
||||
public virtual int Slot { get; set; }
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class BadgeMap : ClassMap<Badge>
|
||||
{
|
||||
public BadgeMap()
|
||||
{
|
||||
Table("habbo_badges");
|
||||
LazyLoad();
|
||||
Id(b => b.Id).Column("id").GeneratedBy.Identity();
|
||||
References(b => b.Habbo).Column("habbo_id").Not.Nullable();
|
||||
Map(b => b.Code).Column("code").Not.Nullable();
|
||||
Map(b => b.Slot).Column("slot").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class Habbo
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Username { get; set; } = null!;
|
||||
public virtual string Email { get; set; } = null!;
|
||||
public virtual DateTime AccountCreated { get; set; }
|
||||
public virtual DateTime? LastLogin { get; set; }
|
||||
public virtual string Motto { get; set; } = null!;
|
||||
public virtual string Figure { get; set; } = null!;
|
||||
public virtual string Gender { get; set; } = null!;
|
||||
public virtual int Rank { get; set; }
|
||||
public virtual int Credits { get; set; }
|
||||
public virtual bool Online { get; set; }
|
||||
public virtual int HomeRoom { get; set; }
|
||||
public virtual int AchievementScore { get; set; }
|
||||
public virtual int? GroupId { get; set; }
|
||||
public virtual string? SsoTicket { get; set; }
|
||||
public virtual IDictionary<int, Activitypoints> Activitypoints { get; set; } = new Dictionary<int, Activitypoints>();
|
||||
public virtual ICollection<Badge> Badges { get; set; } = new List<Badge>();
|
||||
|
||||
public virtual IDictionary<int, HabboAchievement> Achievements { get; set; } = new Dictionary<int, HabboAchievement>();
|
||||
public virtual ICollection<HabboSubscription> Subscriptions { get; set; } = new List<HabboSubscription>();
|
||||
|
||||
public virtual int GetActivityPoints(int type)
|
||||
{
|
||||
return Activitypoints.TryGetValue(type, out var activityPoints) ? activityPoints.Amount : 0;
|
||||
}
|
||||
public virtual void UpdateCurrency(int type, int amount)
|
||||
{
|
||||
if (!Activitypoints.ContainsKey(type))
|
||||
{
|
||||
Activitypoints.Add(type, new Activitypoints
|
||||
{
|
||||
Habbo = this,
|
||||
Amount = amount,
|
||||
Type = type
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Activitypoints[type].Amount += amount;
|
||||
}
|
||||
|
||||
public virtual HabboSubscription? GetActiveSubscription()
|
||||
{
|
||||
return Subscriptions.Where(s => s.Expires > DateTime.Now).MaxBy(s => s.Expires);
|
||||
}
|
||||
|
||||
public virtual int GetPastSubscriptionDays()
|
||||
{
|
||||
int totalDays = 0;
|
||||
|
||||
foreach (var subscription in Subscriptions)
|
||||
{
|
||||
if(subscription.Expires < DateTime.Now) // If subscription has ended
|
||||
{
|
||||
totalDays += (subscription.Expires - subscription.Started).Days;
|
||||
}
|
||||
else if(subscription.Started < DateTime.Now) // If subscription is ongoing
|
||||
{
|
||||
totalDays += (DateTime.Now - subscription.Started).Days;
|
||||
}
|
||||
}
|
||||
|
||||
return totalDays;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using Tiger.Game.Achievements;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class HabboAchievement
|
||||
{
|
||||
public virtual Habbo Habbo { get; set; } = null!;
|
||||
public virtual Achievement Achievement { get; set; } = null!;
|
||||
public virtual int Level { get; set; }
|
||||
public virtual int Progress { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not HabboAchievement other)
|
||||
return false;
|
||||
|
||||
return Habbo.Id == other.Habbo.Id && Achievement.Id == other.Achievement.Id;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hash = 17;
|
||||
hash = hash * 23 + Habbo.Id.GetHashCode();
|
||||
hash = hash * 23 + Achievement.Id.GetHashCode();
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class HabboAchievementMap : ClassMap<HabboAchievement>
|
||||
{
|
||||
public HabboAchievementMap()
|
||||
{
|
||||
Table("habbo_achievements");
|
||||
LazyLoad();
|
||||
CompositeId()
|
||||
.KeyReference(ha => ha.Habbo, "habbo_id")
|
||||
.KeyReference(ha => ha.Achievement, "achievement_id");
|
||||
Map(ha => ha.Level).Column("level").Not.Nullable();
|
||||
Map(ha => ha.Progress).Column("progress").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class HabboMap : ClassMap<Habbo>
|
||||
{
|
||||
public HabboMap()
|
||||
{
|
||||
Table("habbos");
|
||||
LazyLoad();
|
||||
Id(h => h.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(h => h.Username).Column("username").Not.Nullable();
|
||||
Map(h => h.Email).Column("email").Not.Nullable();
|
||||
Map(h => h.AccountCreated).Column("account_created").Not.Nullable();
|
||||
Map(h => h.LastLogin).Column("last_login").Nullable();
|
||||
Map(h => h.Motto).Column("motto").Not.Nullable();
|
||||
Map(h => h.Figure).Column("figure").Not.Nullable();
|
||||
Map(h => h.Gender).Column("gender").Not.Nullable();
|
||||
Map(h => h.Rank).Column("rank").Not.Nullable();
|
||||
Map(h => h.Credits).Column("credits").Not.Nullable();
|
||||
Map(h => h.Online).Column("online").Not.Nullable();
|
||||
Map(h => h.HomeRoom).Column("home_room").Not.Nullable();
|
||||
Map(h => h.AchievementScore).Column("achievement_score").Not.Nullable();
|
||||
Map(h => h.GroupId).Column("group_id").Nullable();
|
||||
Map(h => h.SsoTicket).Column("sso_ticket").Nullable();
|
||||
HasMany(h => h.Activitypoints).AsMap(a => a.Type).Inverse().Cascade.All();
|
||||
HasMany(h => h.Badges).Inverse().Cascade.All();
|
||||
HasMany(x => x.Achievements)
|
||||
.Table("habbo_achievements")
|
||||
.KeyColumn("habbo_id")
|
||||
.Component(comp =>
|
||||
{
|
||||
comp.Map(x => x.Level);
|
||||
comp.Map(x => x.Progress);
|
||||
})
|
||||
.AsMap("achievement_id")
|
||||
.Cascade.All();
|
||||
HasMany(h => h.Subscriptions).Cascade.All().Inverse();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class HabboSubscription
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual Habbo Habbo { get; set; } = null!;
|
||||
public virtual string SubscriptionType { get; set; }= null!;
|
||||
public virtual DateTime Started { get; set; }
|
||||
public virtual DateTime Expires { get; set; }
|
||||
|
||||
public virtual int DaysInMonthLeft => (int)(Expires - DateTime.Now).TotalDays % 31;
|
||||
public virtual int MonthsLeft => (int)(Expires - DateTime.Now).TotalDays / 31;
|
||||
public virtual double MinutesLeft => (Expires - DateTime.Now).TotalMinutes;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Habbos;
|
||||
|
||||
public class HabboSubscriptionMap : ClassMap<HabboSubscription>
|
||||
{
|
||||
public HabboSubscriptionMap()
|
||||
{
|
||||
Table("habbo_subscriptions");
|
||||
LazyLoad();
|
||||
Id(hs => hs.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(hs => hs.SubscriptionType).Column("subscription_type").Not.Nullable();
|
||||
Map(hs => hs.Started).Column("started").Not.Nullable();
|
||||
Map(hs => hs.Expires).Column("expires").Not.Nullable();
|
||||
References(x => x.Habbo).Column("habbo_id").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Tiger.Game.LandingView;
|
||||
|
||||
public interface ILandingViewManager
|
||||
{
|
||||
ICollection<PromoArticle> PromoArticles { get; }
|
||||
Task LoadPromoArticlesAsync();
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.LandingView;
|
||||
|
||||
public class LandingViewManager : ILandingViewManager
|
||||
{
|
||||
private readonly IRepository<PromoArticle> _promoArticleRepository;
|
||||
private readonly ILogger<ILandingViewManager> _logger;
|
||||
|
||||
public LandingViewManager(IRepository<PromoArticle> promoArticleRepository, ILogger<ILandingViewManager> logger)
|
||||
{
|
||||
_promoArticleRepository = promoArticleRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public ICollection<PromoArticle> PromoArticles { get; private set; } = new List<PromoArticle>();
|
||||
|
||||
public async Task LoadPromoArticlesAsync()
|
||||
{
|
||||
PromoArticles = (await _promoArticleRepository.FindByAsync()).ToList();
|
||||
|
||||
_logger.LogInformation("Loaded {Count} promo articles", PromoArticles.Count);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace Tiger.Game.LandingView;
|
||||
|
||||
public class PromoArticle
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Title { get; set; } = null!;
|
||||
public virtual string BodyText { get; set; } = null!;
|
||||
public virtual string ButtonText { get; set; } = null!;
|
||||
public virtual PromoArticleLinkType LinkType { get; set; }
|
||||
public virtual string LinkContent { get; set; } = null!;
|
||||
public virtual string ImageUrl { get; set; } = null!;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Tiger.Game.LandingView;
|
||||
|
||||
public enum PromoArticleLinkType
|
||||
{
|
||||
LinkTypeUrl = 0,
|
||||
LinkTypeInternal = 1,
|
||||
LinkTypeNoLink = 2
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.LandingView;
|
||||
|
||||
public class PromoArticleMap : ClassMap<PromoArticle>
|
||||
{
|
||||
public PromoArticleMap()
|
||||
{
|
||||
Table("landing_promo_articles");
|
||||
Id(pa => pa.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(pa => pa.Title).Column("title").Not.Nullable();
|
||||
Map(pa => pa.BodyText).Column("body_text").Not.Nullable();
|
||||
Map(pa => pa.ButtonText).Column("button_text").Not.Nullable();
|
||||
Map(pa => pa.LinkType).CustomType<int>().Column("link_type").Not.Nullable();
|
||||
Map(pa => pa.LinkContent).Column("link_content").Not.Nullable();
|
||||
Map(pa => pa.ImageUrl).Column("image_url").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
using Tiger.Game.Navigator.Views;
|
||||
|
||||
namespace Tiger.Game.Navigator;
|
||||
|
||||
public interface INavigatorManager
|
||||
{
|
||||
IDictionary<string, INavigatorView> NavigatorViews { get; }
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using Tiger.Game.Navigator.Views;
|
||||
|
||||
namespace Tiger.Game.Navigator;
|
||||
|
||||
public class NavigatorManager : INavigatorManager
|
||||
{
|
||||
public IDictionary<string, INavigatorView> NavigatorViews { get; }
|
||||
|
||||
public NavigatorManager(IEnumerable<INavigatorView> navigatorViews)
|
||||
{
|
||||
NavigatorViews = navigatorViews.ToDictionary(n => n.Code);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Game.Navigator.Views;
|
||||
|
||||
public interface INavigatorView
|
||||
{
|
||||
string Code { get; }
|
||||
Task Compose(ServerMessage message, Habbo habbo, string query);
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Game.Rooms;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Navigator.Views;
|
||||
|
||||
public class MyWorldView : INavigatorView
|
||||
{
|
||||
private readonly IRepository<Room> _roomRepository;
|
||||
|
||||
private const int OwnRoomsType = 0;
|
||||
private const int FavoriteRoomsType = 1;
|
||||
private const int GroupRoomsType = 2;
|
||||
private const int VisitedRoomsType = 3;
|
||||
private const int FriendRoomsType = 4;
|
||||
private const int RightsRoomType = 5;
|
||||
|
||||
public string Code => "myworld_view";
|
||||
|
||||
private readonly IDictionary<string, int> _categories = new Dictionary<string, int>
|
||||
{
|
||||
{"My Rooms", OwnRoomsType},
|
||||
{"My Favorite Rooms", FavoriteRoomsType},
|
||||
{"My Groups", GroupRoomsType},
|
||||
{"My Room Visit History", VisitedRoomsType},
|
||||
{"My Friends' Rooms", FriendRoomsType},
|
||||
{"Rooms Where I Have Rights", RightsRoomType}
|
||||
};
|
||||
|
||||
public MyWorldView(IRepository<Room> roomRepository)
|
||||
{
|
||||
_roomRepository = roomRepository;
|
||||
}
|
||||
|
||||
public async Task Compose(ServerMessage message, Habbo habbo, string query)
|
||||
{
|
||||
message.AppendInt32(_categories.Count);
|
||||
|
||||
foreach (var (category, type) in _categories)
|
||||
{
|
||||
message.AppendString(category);
|
||||
message.AppendString(category);
|
||||
message.AppendInt32(0); // action?
|
||||
message.AppendBoolean(false); // closed?
|
||||
message.AppendInt32(0); // mode?
|
||||
|
||||
var rooms = await GetRoomsByType(habbo, type);
|
||||
|
||||
message.AppendInt32(rooms.Count);
|
||||
|
||||
foreach (var room in rooms)
|
||||
{
|
||||
room.Serialize(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ICollection<Room>> GetRoomsByType(Habbo habbo, int type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
OwnRoomsType => (await _roomRepository.FindByAsync(r => r.Owner == habbo)).ToList(),
|
||||
_ => new Collection<Room>()
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Game.Navigator.Views;
|
||||
|
||||
public class OfficialView : INavigatorView
|
||||
{
|
||||
public string Code => "official_view";
|
||||
public async Task Compose(ServerMessage message, Habbo habbo, string query)
|
||||
{
|
||||
message.AppendInt32(0);
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public interface IRoomManager
|
||||
{
|
||||
IDictionary<int, RoomPrivateCategory> PrivateCategories { get; }
|
||||
IDictionary<int, RoomModel> RoomModels { get; }
|
||||
Task LoadPrivateCategoriesAsync();
|
||||
Task LoadRoomModels();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace Tiger.Game.Rooms.Mapping.Tiles;
|
||||
|
||||
public class RoomTile
|
||||
{
|
||||
public int X { get; set; }
|
||||
public int Y { get; set; }
|
||||
public double Height { get; set; }
|
||||
public RoomTileState TileState { get; set; }
|
||||
|
||||
public RoomTile(int x, int y, double height, RoomTileState tileState)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Height = height;
|
||||
TileState = tileState;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
namespace Tiger.Game.Rooms.Mapping.Tiles;
|
||||
|
||||
/// <summary>
|
||||
/// Empty and Unavailable can be set in both the RoomTile and RoomPoint.
|
||||
/// RoomTile belongs to the Model (the tile is either unavailable or empty)
|
||||
/// RoomPoint belongs to the Grid (the tile has multiple states based on once actors and items are added)
|
||||
/// </summary>
|
||||
public enum RoomTileState
|
||||
{
|
||||
Empty,
|
||||
Unavailable,
|
||||
HasWalkableStackableItem,
|
||||
WalkBlockedByItem,
|
||||
StackBlockedByItem,
|
||||
TileLockedByItem,
|
||||
BlockedByUser
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class Room
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; } = null!;
|
||||
public virtual string Description { get; set; } = null!;
|
||||
public virtual int ModelId { get; set; }
|
||||
public virtual string Password { get; set; } = null!;
|
||||
public virtual string State { get; set; } = null!;
|
||||
public virtual int UsersIn { get; set; }
|
||||
public virtual int UsersMax { get; set; }
|
||||
public virtual int Score { get; set; }
|
||||
public virtual string Floor { get; set; } = null!;
|
||||
public virtual string Wallpaper { get; set; } = null!;
|
||||
public virtual string Landscape { get; set; } = null!;
|
||||
public virtual int WallThickness { get; set; }
|
||||
public virtual int WallHeight { get; set; }
|
||||
public virtual int FloorThickness { get; set; }
|
||||
public virtual string MoodlightData { get; set; } = null!;
|
||||
public virtual IList<string> Tags { get; set; } = new List<string>();
|
||||
public virtual bool IsPublic { get; set; }
|
||||
public virtual bool IsStaffPicked { get; set; }
|
||||
public virtual bool AllowOtherPets { get; set; }
|
||||
public virtual bool AllowOtherPetsEat { get; set; }
|
||||
public virtual bool AllowWalkthrough { get; set; }
|
||||
public virtual bool HideWalls { get; set; }
|
||||
public virtual int ChatMode { get; set; }
|
||||
public virtual int ChatWeight { get; set; }
|
||||
public virtual int ChatSpeed { get; set; }
|
||||
public virtual int ChatHearingDistance { get; set; }
|
||||
public virtual int ChatProtection { get; set; }
|
||||
public virtual bool OverrideModel { get; set; }
|
||||
public virtual int WhoCanMute { get; set; }
|
||||
public virtual int WhoCanKick { get; set; }
|
||||
public virtual int WhoCanBan { get; set; }
|
||||
public virtual int RollerSpeed { get; set; }
|
||||
public virtual bool Promoted { get; set; }
|
||||
public virtual int TradeMode { get; set; }
|
||||
public virtual bool MoveDiagonally { get; set; }
|
||||
public virtual bool JukeboxActive { get; set; }
|
||||
public virtual bool HideWired { get; set; }
|
||||
public virtual bool IsForSale { get; set; }
|
||||
public virtual Habbo? Owner { get; set; }
|
||||
public virtual RoomPrivateCategory Category { get; set; } = null!;
|
||||
|
||||
public virtual int StateNumber => State switch
|
||||
{
|
||||
"locked" => 1,
|
||||
"password" => 2,
|
||||
"invisible" => 3,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
public virtual int Base
|
||||
{
|
||||
get
|
||||
{
|
||||
var @base = 0;
|
||||
|
||||
// if (Guild != null)
|
||||
// {
|
||||
// @base += 2;
|
||||
// }
|
||||
|
||||
// if (Promoted)
|
||||
// {
|
||||
// @base += 4;
|
||||
// }
|
||||
|
||||
if (!IsPublic)
|
||||
{
|
||||
@base += 8;
|
||||
}
|
||||
|
||||
if (!IsPublic && AllowOtherPets)
|
||||
{
|
||||
@base += 16;
|
||||
}
|
||||
|
||||
return @base;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Serialize(ServerMessage response)
|
||||
{
|
||||
response.AppendInt32(Id);
|
||||
response.AppendString(Name);
|
||||
|
||||
if (IsPublic)
|
||||
{
|
||||
response.AppendInt32(0);
|
||||
response.AppendString(string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.AppendInt32(Owner?.Id ?? 0);
|
||||
response.AppendString(Owner?.Username ?? string.Empty);
|
||||
}
|
||||
|
||||
response.AppendInt32(StateNumber);
|
||||
response.AppendInt32(UsersIn);
|
||||
response.AppendInt32(UsersMax);
|
||||
response.AppendString(Description);
|
||||
response.AppendInt32(0);
|
||||
response.AppendInt32(Score);
|
||||
response.AppendInt32(0);
|
||||
response.AppendInt32(Category.Id);
|
||||
|
||||
response.AppendInt32(Tags.Count);
|
||||
|
||||
foreach (var tag in Tags)
|
||||
{
|
||||
response.AppendString(tag);
|
||||
}
|
||||
|
||||
response.AppendInt32(Base);
|
||||
|
||||
// if (Guild != null)
|
||||
// {
|
||||
// response.AppendInt32(Guild.Id);
|
||||
// response.WriteString(Guild.Name);
|
||||
// response.WriteString(Guild.Badge);
|
||||
// }
|
||||
|
||||
// TODO: Promotion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomManager : IRoomManager
|
||||
{
|
||||
private readonly IRepository<RoomPrivateCategory> _roomPrivateCategoryRepository;
|
||||
private readonly IRepository<RoomModel> _roomModelRepository;
|
||||
private readonly ILogger<IRoomManager> _logger;
|
||||
|
||||
public IDictionary<int, RoomPrivateCategory> PrivateCategories { get; private set; }
|
||||
public IDictionary<int, RoomModel> RoomModels { get; private set; }
|
||||
|
||||
public RoomManager(IRepository<RoomPrivateCategory> roomPrivateCategoryRepository,
|
||||
IRepository<RoomModel> roomModelRepository, ILogger<IRoomManager> logger)
|
||||
{
|
||||
_roomPrivateCategoryRepository = roomPrivateCategoryRepository;
|
||||
_roomModelRepository = roomModelRepository;
|
||||
_logger = logger;
|
||||
|
||||
PrivateCategories = new Dictionary<int, RoomPrivateCategory>();
|
||||
RoomModels = new Dictionary<int, RoomModel>();
|
||||
}
|
||||
|
||||
public async Task LoadPrivateCategoriesAsync()
|
||||
{
|
||||
PrivateCategories =
|
||||
(await _roomPrivateCategoryRepository.FindByAsync()).ToDictionary(rpc => rpc.Id);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} private room categories", PrivateCategories.Count);
|
||||
}
|
||||
|
||||
public async Task LoadRoomModels()
|
||||
{
|
||||
RoomModels = (await _roomModelRepository.FindByAsync()).ToDictionary(rpc => rpc.Id);
|
||||
|
||||
foreach (var model in RoomModels.Values)
|
||||
{
|
||||
model.Parse();
|
||||
}
|
||||
|
||||
_logger.LogInformation("Loaded and parsed {Count} room models", RoomModels.Count);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomMap : ClassMap<Room>
|
||||
{
|
||||
public RoomMap()
|
||||
{
|
||||
Table("rooms");
|
||||
Id(x => x.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(x => x.Name).Column("name").Not.Nullable();
|
||||
Map(x => x.Description).Column("description").Not.Nullable();
|
||||
Map(x => x.ModelId).Column("model_id").Not.Nullable();
|
||||
Map(x => x.Password).Column("password").Nullable();
|
||||
Map(x => x.State).Column("state").Not.Nullable();
|
||||
Map(x => x.UsersIn).Column("users_in").Not.Nullable();
|
||||
Map(x => x.UsersMax).Column("users_max").Not.Nullable();
|
||||
Map(x => x.Score).Column("score").Not.Nullable();
|
||||
Map(x => x.Floor).Column("floor").Not.Nullable();
|
||||
Map(x => x.Wallpaper).Column("wallpaper").Not.Nullable();
|
||||
Map(x => x.Landscape).Column("landscape").Not.Nullable();
|
||||
Map(x => x.WallThickness).Column("wall_thickness").Not.Nullable();
|
||||
Map(x => x.WallHeight).Column("wall_height").Not.Nullable();
|
||||
Map(x => x.FloorThickness).Column("floor_thickness").Not.Nullable();
|
||||
Map(x => x.MoodlightData).Column("moodlight_data").Nullable();
|
||||
Map(x => x.Tags).Column("tags").CustomType<StringListTypeConverter>().Nullable();
|
||||
Map(x => x.IsPublic).Column("is_public").Not.Nullable();
|
||||
Map(x => x.IsStaffPicked).Column("is_staff_picked").Not.Nullable();
|
||||
Map(x => x.AllowOtherPets).Column("allow_other_pets").Not.Nullable();
|
||||
Map(x => x.AllowOtherPetsEat).Column("allow_other_pets_eat").Not.Nullable();
|
||||
Map(x => x.AllowWalkthrough).Column("allow_walkthrough").Not.Nullable();
|
||||
Map(x => x.HideWalls).Column("hide_walls").Not.Nullable();
|
||||
Map(x => x.ChatMode).Column("chat_mode").Not.Nullable();
|
||||
Map(x => x.ChatWeight).Column("chat_weight").Not.Nullable();
|
||||
Map(x => x.ChatSpeed).Column("chat_speed").Not.Nullable();
|
||||
Map(x => x.ChatHearingDistance).Column("chat_hearing_distance").Not.Nullable();
|
||||
Map(x => x.ChatProtection).Column("chat_protection").Not.Nullable();
|
||||
Map(x => x.OverrideModel).Column("override_model").Not.Nullable();
|
||||
Map(x => x.WhoCanMute).Column("who_can_mute").Not.Nullable();
|
||||
Map(x => x.WhoCanKick).Column("who_can_kick").Not.Nullable();
|
||||
Map(x => x.WhoCanBan).Column("who_can_ban").Not.Nullable();
|
||||
Map(x => x.RollerSpeed).Column("roller_speed").Not.Nullable();
|
||||
Map(x => x.Promoted).Column("promoted").Not.Nullable();
|
||||
Map(x => x.TradeMode).Column("trade_mode").Not.Nullable();
|
||||
Map(x => x.MoveDiagonally).Column("move_diagonally").Not.Nullable();
|
||||
Map(x => x.JukeboxActive).Column("jukebox_active").Not.Nullable();
|
||||
Map(x => x.HideWired).Column("hide_wired").Not.Nullable();
|
||||
Map(x => x.IsForSale).Column("is_for_sale").Not.Nullable();
|
||||
References(x => x.Owner).Column("owner_id").Nullable();
|
||||
References(x => x.Category).Column("category_id").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
using Tiger.Game.Rooms.Mapping.Tiles;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomModel
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual string Name { get; set; } = null!;
|
||||
public virtual int DoorX { get; set; }
|
||||
public virtual int DoorY { get; set; }
|
||||
public virtual int DoorDirection { get; set; }
|
||||
public virtual string Heightmap { get; set; } = null!;
|
||||
|
||||
public virtual (int X, int Y) MapSize { get; set; }
|
||||
|
||||
public virtual RoomTile[,] RoomTiles { get; set; }
|
||||
|
||||
public virtual void Parse()
|
||||
{
|
||||
var raw = Heightmap.Replace("\r\n", "\r").Split('\r');
|
||||
|
||||
MapSize = (raw[0].Length, raw.Length);
|
||||
|
||||
RoomTiles = new RoomTile[MapSize.X, MapSize.Y];
|
||||
|
||||
for (var y = 0; y < MapSize.Y; y++)
|
||||
{
|
||||
for (var x = 0; x < MapSize.X; x++)
|
||||
{
|
||||
if (double.TryParse(raw[y][x].ToString(), out var height))
|
||||
{
|
||||
RoomTiles[x, y] = new RoomTile(x, y, height, RoomTileState.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
RoomTiles[x, y] = new RoomTile(x, y, 0, RoomTileState.Unavailable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomModelMap : ClassMap<RoomModel>
|
||||
{
|
||||
public RoomModelMap()
|
||||
{
|
||||
Table("room_models");
|
||||
LazyLoad();
|
||||
Id(rm => rm.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(rm => rm.Name).Column("name").Not.Nullable();
|
||||
Map(rm => rm.DoorX).Column("door_x").Not.Nullable();
|
||||
Map(rm => rm.DoorY).Column("door_y").Not.Nullable();
|
||||
Map(rm => rm.DoorDirection).Column("door_direction").Not.Nullable();
|
||||
Map(rm => rm.Heightmap).Column("heightmap").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomPrivateCategory
|
||||
{
|
||||
public virtual int Id { get; set; }
|
||||
public virtual int MinRank { get; set; }
|
||||
public virtual string Code { get; set; } = null!;
|
||||
public virtual string Name { get; set; } = null!;
|
||||
public virtual bool CanTrade { get; set; }
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Rooms;
|
||||
|
||||
public class RoomPrivateCategoryMap : ClassMap<RoomPrivateCategory>
|
||||
{
|
||||
public RoomPrivateCategoryMap()
|
||||
{
|
||||
Table("room_private_categories");
|
||||
LazyLoad();
|
||||
Id(rpc => rpc.Id).Column("id").GeneratedBy.Identity();
|
||||
Map(rpc => rpc.MinRank).Column("min_rank").Not.Nullable();
|
||||
Map(rpc => rpc.Code).Column("code").Not.Nullable();
|
||||
Map(rpc => rpc.Name).Column("name").Not.Nullable();
|
||||
Map(rpc => rpc.CanTrade).Column("can_trade").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Tiger.Game.Settings;
|
||||
|
||||
public interface ISettingManager
|
||||
{
|
||||
Task ReloadSettingsAsync();
|
||||
T GetSetting<T>(string key);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
namespace Tiger.Game.Settings;
|
||||
|
||||
public class Setting
|
||||
{
|
||||
public virtual string Key { get; set; } = null!;
|
||||
public virtual string Value { get; set; } = null!;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Storage;
|
||||
|
||||
namespace Tiger.Game.Settings;
|
||||
|
||||
public class SettingManager : ISettingManager
|
||||
{
|
||||
private IReadOnlyDictionary<string, string> _settings;
|
||||
private readonly IRepository<Setting> _settingRepository;
|
||||
private readonly ILogger<ISettingManager> _logger;
|
||||
|
||||
public SettingManager(IRepository<Setting> settingRepository, ILogger<ISettingManager> logger)
|
||||
{
|
||||
_settingRepository = settingRepository;
|
||||
_logger = logger;
|
||||
_settings = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
public async Task ReloadSettingsAsync()
|
||||
{
|
||||
_settings = (await _settingRepository.FindByAsync()).ToDictionary(s => s.Key, s => s.Value);
|
||||
|
||||
_logger.LogInformation("Loaded {Count} settings", _settings.Count);
|
||||
}
|
||||
|
||||
public T GetSetting<T>(string key)
|
||||
{
|
||||
if (!_settings.TryGetValue(key, out var value))
|
||||
throw new KeyNotFoundException($"No setting found with key '{key}'");
|
||||
|
||||
if (value is T castedValue)
|
||||
return castedValue;
|
||||
|
||||
throw new InvalidCastException($"Setting '{key}' is not of type '{typeof(T)}'");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
using FluentNHibernate.Mapping;
|
||||
|
||||
namespace Tiger.Game.Settings;
|
||||
|
||||
public class SettingMap : ClassMap<Setting>
|
||||
{
|
||||
public SettingMap()
|
||||
{
|
||||
Table("settings");
|
||||
Id(s => s.Key).Column("skey").Not.Nullable();
|
||||
Map(s => s.Value).Column("value").Not.Nullable();
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Net.WebSockets;
|
||||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
|
||||
namespace Tiger.Networking.Game.Sessions;
|
||||
|
||||
|
@ -8,6 +9,7 @@ public class GameSession
|
|||
{
|
||||
public WebSocket WebSocket { get; }
|
||||
public string SessionId { get; }
|
||||
public Habbo? Habbo { get; set; }
|
||||
|
||||
public GameSession(WebSocket webSocket, string sessionId)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Net.WebSockets;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Communication.Messages;
|
||||
using Tiger.Communication.Messages.Types;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
using Tiger.Utils;
|
||||
|
@ -14,12 +15,14 @@ public class WebSocketServer : IWebSocketServer
|
|||
private readonly HttpListener _httpListener = new();
|
||||
private readonly IGameSessionManager _gameSessionManager;
|
||||
private readonly IMessageHandler _messageHandler;
|
||||
private readonly IRepository<Habbo> _habboRepository;
|
||||
private readonly ILogger<IWebSocketServer> _logger;
|
||||
|
||||
public WebSocketServer(IGameSessionManager gameSessionManager, IMessageHandler messageHandler, ILogger<IWebSocketServer> logger)
|
||||
public WebSocketServer(IGameSessionManager gameSessionManager, IMessageHandler messageHandler, IRepository<Habbo> habboRepository, ILogger<IWebSocketServer> logger)
|
||||
{
|
||||
_gameSessionManager = gameSessionManager;
|
||||
_messageHandler = messageHandler;
|
||||
_habboRepository = habboRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
@ -104,5 +107,12 @@ public class WebSocketServer : IWebSocketServer
|
|||
await gameSession.WebSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
|
||||
}
|
||||
}
|
||||
|
||||
if (gameSession is { Habbo: not null })
|
||||
{
|
||||
gameSession.Habbo.Online = false;
|
||||
await _habboRepository.SaveAsync(gameSession.Habbo);
|
||||
_logger.LogInformation("{User} logged out", gameSession.Habbo.Username);
|
||||
}
|
||||
}
|
||||
}
|
27
Program.cs
27
Program.cs
|
@ -4,6 +4,15 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Tiger.Communication.Messages;
|
||||
using Tiger.Communication.Messages.Interfaces;
|
||||
using Tiger.Game.Achievements;
|
||||
using Tiger.Game.Catalogue;
|
||||
using Tiger.Game.Figuredata;
|
||||
using Tiger.Game.Habbos;
|
||||
using Tiger.Game.LandingView;
|
||||
using Tiger.Game.Navigator;
|
||||
using Tiger.Game.Navigator.Views;
|
||||
using Tiger.Game.Rooms;
|
||||
using Tiger.Game.Settings;
|
||||
using Tiger.Networking.Game;
|
||||
using Tiger.Networking.Game.Sessions;
|
||||
using Tiger.Storage;
|
||||
|
@ -31,10 +40,28 @@ collection.AddSingleton<IMessageHandler, MessageHandler>();
|
|||
collection.AddSingleton<INhSessionFactory, NhSessionFactory>();
|
||||
collection.AddScoped(serviceProvider => serviceProvider.GetRequiredService<INhSessionFactory>().OpenSession());
|
||||
collection.AddScoped(typeof(IRepository<>), typeof(Repository<>));
|
||||
collection.AddSingleton<ISettingManager, SettingManager>();
|
||||
collection.AddSingleton<ICatalogueManager, CatalogueManager>();
|
||||
collection.AddSingleton<IFigureDataManager, FiguredataManager>();
|
||||
collection.AddSingleton<ILandingViewManager, LandingViewManager>();
|
||||
collection.AddSingleton<IAchievementManager, AchievementManager>();
|
||||
collection.AddSingleton<INavigatorManager, NavigatorManager>();
|
||||
collection.AddSingleton<IRoomManager, RoomManager>();
|
||||
collection.RegisterOnInherited<IMessageEvent>();
|
||||
collection.RegisterOnInherited<INavigatorView>();
|
||||
|
||||
var provider = collection.BuildServiceProvider();
|
||||
|
||||
await provider.GetRequiredService<ISettingManager>().ReloadSettingsAsync();
|
||||
await provider.GetRequiredService<ICatalogueManager>().LoadPagesAsync();
|
||||
await provider.GetRequiredService<ICatalogueManager>().LoadFeaturedPagesAsync();
|
||||
await provider.GetRequiredService<ICatalogueManager>().LoadClubOffersAsync();
|
||||
provider.GetRequiredService<IFigureDataManager>();
|
||||
await provider.GetRequiredService<ILandingViewManager>().LoadPromoArticlesAsync();
|
||||
await provider.GetRequiredService<IAchievementManager>().LoadAchievementsAsync();
|
||||
await provider.GetRequiredService<IRoomManager>().LoadPrivateCategoriesAsync();
|
||||
await provider.GetRequiredService<IRoomManager>().LoadRoomModels();
|
||||
|
||||
provider.GetRequiredService<IWebSocketServer>().Start($"http://{configuration["Network:Game:Ip"]}:{configuration["Network:Game:Port"]}/");
|
||||
|
||||
quitEvent.WaitOne();
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue