Initial commit
commit
d5efddd10d
|
@ -0,0 +1,2 @@
|
|||
.idea/
|
||||
vendor/
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"require": {
|
||||
"react/event-loop": "^1.5",
|
||||
"react/http": "^1.9",
|
||||
"react/stream": "^1.3",
|
||||
"react/async": "^4.2",
|
||||
"react/promise": "^3.1",
|
||||
"react/socket": "^1.15",
|
||||
"cboden/ratchet": "^0.4.4"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
require_once 'vendor/autoload.php';
|
||||
|
||||
spl_autoload_register(function(string $class) {
|
||||
require_once str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
|
||||
});
|
||||
|
||||
use Emulator\HabboEnvironment;
|
||||
|
||||
HabboEnvironment::getInstance()->initialize();
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Core\Logging;
|
||||
|
||||
enum LogLevel {
|
||||
case Debug;
|
||||
case Info;
|
||||
case Warn;
|
||||
case Fatal;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Core\Logging;
|
||||
|
||||
class Logger {
|
||||
private const array colorCodes = [
|
||||
'r' => 31,
|
||||
'b' => 34
|
||||
];
|
||||
|
||||
public static function log(LogLevel $level, string $text): void {
|
||||
if (preg_match_all('/\[([a-z]{1,2})]/', $text, $matches)) {
|
||||
foreach ($matches[1] as $code) {
|
||||
$colorCode = self::colorCodes[$code];
|
||||
$text = str_replace(["[$code]", "[/$code]"], ["\033[{$colorCode}m", "\033[0m"], $text);
|
||||
}
|
||||
}
|
||||
|
||||
echo "[$level->name] $text" . PHP_EOL;
|
||||
}
|
||||
|
||||
public static function debug(string $text): void {
|
||||
self::log(LogLevel::Debug, $text);
|
||||
}
|
||||
|
||||
public static function info(string $text): void {
|
||||
self::log(LogLevel::Info, $text);
|
||||
}
|
||||
|
||||
public static function warn(string $text): void {
|
||||
self::log(LogLevel::Warn, $text);
|
||||
}
|
||||
|
||||
public static function fatal(string $text): void {
|
||||
self::log(LogLevel::Fatal, $text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Encoding;
|
||||
|
||||
class ByteEncoding {
|
||||
public static function getInt32(array $raw): int{
|
||||
|
||||
return ($raw[0] << 24) | ($raw[1] << 16) | ($raw[2] << 8) | $raw[3];
|
||||
}
|
||||
|
||||
public static function getInt16(array $raw): int {
|
||||
return (($raw[0] << 8) | $raw[1]);
|
||||
}
|
||||
|
||||
public static function int32ToArray(int $value): array {
|
||||
return [$value >> 24, $value >> 16, $value >> 8, $value];
|
||||
}
|
||||
|
||||
public static function int16ToArray(int $value): array {
|
||||
return [$value >> 8, $value];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator;
|
||||
|
||||
use Emulator\Core\Logging\Logger;
|
||||
use Emulator\Messages\MessageHandler;
|
||||
use Emulator\Network\Game\GameNetworkServer;
|
||||
|
||||
class HabboEnvironment {
|
||||
private static ?HabboEnvironment $instance = null;
|
||||
|
||||
public function initialize(): void {
|
||||
Logger::info("Starting up [b]HabboEmulator[/b] (PHP Edition) for [r]$_SERVER[USER][/r]");
|
||||
|
||||
MessageHandler::getInstance();
|
||||
|
||||
GameNetworkServer::getInstance()->start(2096);
|
||||
}
|
||||
|
||||
public static function getInstance(): HabboEnvironment {
|
||||
if (self::$instance === null)
|
||||
self::$instance = new self();
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Incoming;
|
||||
|
||||
use Emulator\Encoding\ByteEncoding;
|
||||
|
||||
class ClientMessage {
|
||||
private readonly array $packet;
|
||||
private readonly int $header;
|
||||
private int $readerIndex;
|
||||
|
||||
public function __construct(array $packet) {
|
||||
$this->packet = $packet;
|
||||
$this->readerIndex = 0;
|
||||
$this->header = $this->readInt16();
|
||||
}
|
||||
|
||||
private function readBytes(int $amount): array {
|
||||
$bytes = [];
|
||||
for ($i = 0; $i < $amount && $this->readerIndex < count($this->packet); $i++) {
|
||||
$bytes[$i] = $this->packet[$this->readerIndex++];
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
public function readInt16(): int {
|
||||
return ByteEncoding::getInt16($this->readBytes(2));
|
||||
}
|
||||
|
||||
public function readInt32(): int {
|
||||
return ByteEncoding::getInt32($this->readBytes(4));
|
||||
}
|
||||
|
||||
public function readBoolean(): bool {
|
||||
return $this->packet[$this->readerIndex++] === 1;
|
||||
}
|
||||
|
||||
public function readString(): string {
|
||||
return call_user_func_array('pack', array_merge(['C*'], $this->readBytes($this->readInt16())));
|
||||
}
|
||||
|
||||
public function getHeader(): int{
|
||||
return $this->header;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Incoming\Handshake;
|
||||
|
||||
use Emulator\Messages\Incoming\ClientMessage;
|
||||
use Emulator\Messages\Incoming\Header;
|
||||
use Emulator\Messages\Incoming\IMessageEvent;
|
||||
use Emulator\Network\Game\Sessions\Session;
|
||||
use Override;
|
||||
|
||||
class ReleaseVersionMessageEvent implements IMessageEvent {
|
||||
#[Override] function handle(Session $session, ClientMessage $clientMessage): void {
|
||||
}
|
||||
|
||||
#[Override] function getHeader(): Header {
|
||||
return Header::ReleaseVersion;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Incoming\Handshake;
|
||||
|
||||
use Emulator\Messages\Incoming\ClientMessage;
|
||||
use Emulator\Messages\Incoming\Header;
|
||||
use Emulator\Messages\Incoming\IMessageEvent;
|
||||
use Emulator\Messages\Outgoing\Handshake\AuthenticatedComposer;
|
||||
use Emulator\Network\Game\Sessions\Session;
|
||||
use Override;
|
||||
|
||||
class SecurityTicketMessageEvent implements IMessageEvent {
|
||||
#[Override] function handle(Session $session, ClientMessage $clientMessage): void {
|
||||
$session->sendComposer(new AuthenticatedComposer());
|
||||
}
|
||||
|
||||
#[Override] function getHeader(): Header {
|
||||
return Header::ReleaseVersion;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Incoming;
|
||||
|
||||
enum Header : int
|
||||
{
|
||||
case AchievementList = 219;
|
||||
case Authentication = -1;
|
||||
case BotConfiguration = 1986;
|
||||
case BotPickup = 3323;
|
||||
case BotPlace = 1592;
|
||||
case BotSkillSave = 2624;
|
||||
case GetClubOffers = 3285;
|
||||
case GetClubGiftInfo = 487;
|
||||
case GetCatalogIndex = 1195;
|
||||
case GetCatalogPage = 412;
|
||||
case CatalogPurchase = 3492;
|
||||
case CatalogPurchaseGift = 1411;
|
||||
case GetProductOffer = 2594;
|
||||
case ClientLatency = 295;
|
||||
case ClientLatencyMeasure = 96;
|
||||
case ClientPolicy = 26979;
|
||||
case ClientPong = 2596;
|
||||
case ClientToolbarToggle = 2313;
|
||||
case ClientVariables = 1053;
|
||||
case GetCurrentTimingCode = 2912;
|
||||
case DesktopView = 105;
|
||||
case GetBundleDiscountRuleset = 223;
|
||||
case EventTracker = 3457;
|
||||
case FindNewFriends = 516;
|
||||
case FurnitureAliases = 3898;
|
||||
case FurnitureFloorUpdate = 248;
|
||||
case FurnitureMultistate = 99;
|
||||
case FurniturePickup = 3456;
|
||||
case FurniturePlace = 1258;
|
||||
case FurniturePostitPlace = 2248;
|
||||
case FurniturePostitSaveStickyPole = 3283;
|
||||
case FurnitureRandomstate = 3617;
|
||||
case FurnitureWallMultistate = 210;
|
||||
case FurnitureWallUpdate = 168;
|
||||
case GamesInit = 2914;
|
||||
case GamesList = 741;
|
||||
case Acceptgameinvite = 3802;
|
||||
case Gameunloadedmessage = 3207;
|
||||
case Getgameachievementsmessage = 2399;
|
||||
case Getgamestatusmessage = 3171;
|
||||
case Getusergameachievementsmessage = 389;
|
||||
case Joinqueuemessage = 1458;
|
||||
case Leavequeuemessage = 2384;
|
||||
case Resetresolutionachievementmessage = 3144;
|
||||
case Getweeklygamerewardwinners = 1054;
|
||||
case Game2Getaccountgamestatusmessage = 11;
|
||||
case Game2Checkgamedirectorystatusmessage = 3259;
|
||||
case Game2Exitgamemessage = 1445;
|
||||
case Game2Gamechatmessage = 2502;
|
||||
case Game2Loadstagereadymessage = 2415;
|
||||
case Game2Playagainmessage = 3196;
|
||||
case Game2Requestfullstatusupdatemessage = 1598;
|
||||
case Game2Getweeklyfriendsleaderboard = 1232;
|
||||
case Game2Getweeklyleaderboard = 2565;
|
||||
case GetGiftWrappingConfig = 418;
|
||||
case GroupAdminAdd = 2894;
|
||||
case GroupAdminRemove = 722;
|
||||
case GroupCreateOptions = 798;
|
||||
case GroupFavorite = 3549;
|
||||
case GetForumStats = 3149;
|
||||
case GetForumThreads = 873;
|
||||
case GetForumsList = 436;
|
||||
case GetForumMessages = 232;
|
||||
case GetForumThread = 3900;
|
||||
case GetUnreadForumsCount = 2908;
|
||||
case ForumModerateMessage = 286;
|
||||
case ForumModerateThread = 1397;
|
||||
case ForumPostMessage = 3529;
|
||||
case UpdateForumReadMarker = 1855;
|
||||
case UpdateForumSettings = 2214;
|
||||
case ForumUpdateThread = 3045;
|
||||
case GroupInfo = 2991;
|
||||
case GroupDelete = 1134;
|
||||
case GroupMemberRemoveConfirm = 3593;
|
||||
case GroupMemberRemove = 593;
|
||||
case GroupMembers = 312;
|
||||
case GroupMemberships = 367;
|
||||
case GroupRequest = 998;
|
||||
case GroupRequestAccept = 3386;
|
||||
case GroupRequestDecline = 1894;
|
||||
case GroupSettings = 1004;
|
||||
case GroupParts = 813;
|
||||
case GroupBuy = 230;
|
||||
case GroupSaveInformation = 3137;
|
||||
case GroupSaveBadge = 1991;
|
||||
case GroupSaveColors = 1764;
|
||||
case GroupSavePreferences = 3435;
|
||||
case GroupBadges = 21;
|
||||
case GroupUnblockMember = 2864;
|
||||
case GetBadgePointsLimits = 1371;
|
||||
case Requestabadge = 3077;
|
||||
case Getisbadgerequestfulfilled = 1364;
|
||||
case ItemClothingRedeem = 3374;
|
||||
case ItemColorWheelClick = 2144;
|
||||
case ItemDiceClick = 1990;
|
||||
case ItemDiceClose = 1533;
|
||||
case ItemDimmerSave = 1648;
|
||||
case ItemDimmerSettings = 2813;
|
||||
case ItemDimmerToggle = 2296;
|
||||
case ItemExchangeRedeem = 3115;
|
||||
case ItemPaint = 711;
|
||||
case SetObjectData = 3608;
|
||||
case ItemStackHelper = 3839;
|
||||
case MarketplaceConfig = 2597;
|
||||
case AcceptFriend = 137;
|
||||
case MessengerChat = 3567;
|
||||
case DeclineFriend = 2890;
|
||||
case FollowFriend = 3997;
|
||||
case MessengerFriends = 1523;
|
||||
case MessengerInit = 2781;
|
||||
case MessengerRelationships = 2138;
|
||||
case SetRelationshipStatus = 3768;
|
||||
case RemoveFriend = 1689;
|
||||
case RequestFriend = 3157;
|
||||
case GetFriendRequests = 2448;
|
||||
case SendRoomInvite = 1276;
|
||||
case HabboSearch = 1210;
|
||||
case FriendListUpdate = 1419;
|
||||
case ModToolUserInfo = 3295;
|
||||
case GetUserFlatCats = 3027;
|
||||
case NavigatorInit = 2110;
|
||||
case NavigatorSearch = 249;
|
||||
case NavigatorSearchClose = 1834;
|
||||
case NavigatorSearchOpen = 637;
|
||||
case NavigatorSearchSave = 2226;
|
||||
case GetUserEventCats = 1782;
|
||||
case NavigatorSettingsSave = 3159;
|
||||
case NavigatorCategoryListMode = 1202;
|
||||
case NavigatorDeleteSavedSearch = 1954;
|
||||
case PetInfo = 2934;
|
||||
case PetPickup = 1581;
|
||||
case PetPlace = 2647;
|
||||
case PetRespect = 3202;
|
||||
case PetRide = 1036;
|
||||
case PetMove = 3449;
|
||||
case PetOpenPackage = 3698;
|
||||
case PetSelected = 549;
|
||||
case PetsBreed = 1638;
|
||||
case PetCancelBreeding = 2713;
|
||||
case PetConfirmBreeding = 3382;
|
||||
case GetPetTrainingPanel = 2161;
|
||||
case RecyclerPrizes = 398;
|
||||
case RecyclerStatus = 1342;
|
||||
case RecyclerItems = 2771;
|
||||
case ReleaseVersion = 4000;
|
||||
case CallForHelp = 1691;
|
||||
case RoomAmbassadorAlert = 2996;
|
||||
case RoomBanGive = 1477;
|
||||
case RoomBanList = 2267;
|
||||
case RoomBanRemove = 992;
|
||||
case RoomCreate = 2752;
|
||||
case RoomDelete = 532;
|
||||
case RoomDoorbell = 1644;
|
||||
case RoomEnter = 2312;
|
||||
case RoomFavorite = 3817;
|
||||
case RoomFavoriteRemove = 309;
|
||||
case CanCreateRoom = 2128;
|
||||
case CancelRoomEvent = 2725;
|
||||
case EditRoomEvent = 3991;
|
||||
case CompetitionRoomSearch = 433;
|
||||
case ForwardToRandomPromotedRoom = 10;
|
||||
case ForwardToSomeRoom = 1703;
|
||||
case GetCategoriesWithUserCount = 3782;
|
||||
case GetGuestRoom = 2230;
|
||||
case GetOfficialRooms = 1229;
|
||||
case GetPopularRoomTags = 826;
|
||||
case GuildBaseSearch = 2930;
|
||||
case MyFavouriteRoomsSearch = 2578;
|
||||
case MyFrequentRoomHistorySearch = 1002;
|
||||
case MyFriendsRoomSearch = 2266;
|
||||
case MyGuildBasesSearch = 39;
|
||||
case MyRecommendedRooms = 2537;
|
||||
case MyRoomHistorySearch = 2264;
|
||||
case MyRoomRightsSearch = 272;
|
||||
case MyRoomsSearch = 2277;
|
||||
case PopularRoomsSearch = 2758;
|
||||
case RoomAdEventTabClicked = 2412;
|
||||
case RoomAdEventTabViewed = 2668;
|
||||
case RoomAdSearch = 2809;
|
||||
case RoomTextSearch = 3943;
|
||||
case RoomsWhereMyFriendsAre = 1786;
|
||||
case RoomsWithHighestScoreSearch = 2939;
|
||||
case SetRoomSessionTags = 3305;
|
||||
case UpdateRoomThumbnail = 2468;
|
||||
case RoomKick = 1320;
|
||||
case RoomLike = 3582;
|
||||
case RoomModel = 2300;
|
||||
case GetOccupiedTiles = 1687;
|
||||
case GetRoomEntryTile = 3559;
|
||||
case RoomModelSave = 875;
|
||||
case RoomMute = 3637;
|
||||
case RoomMuteUser = 3485;
|
||||
case RoomRightsGive = 808;
|
||||
case RoomRightsList = 3385;
|
||||
case RoomRightsRemove = 2064;
|
||||
case RoomRightsRemoveAll = 2683;
|
||||
case RoomRightsRemoveOwn = 3182;
|
||||
case RoomSettings = 3129;
|
||||
case RoomSettingsSave = 1969;
|
||||
case RoomSettingsUpdateRoomCategoryAndTrade = 1265;
|
||||
case RoomStaffPick = 1918;
|
||||
case RoomFilterWords = 1911;
|
||||
case RoomFilterWordsModify = 3001;
|
||||
case Mysteryboxwaitingcanceledmessage = 2012;
|
||||
case MysteryboxOpenTrophy = 3074;
|
||||
case SecurityMachine = 2490;
|
||||
case SecurityTicket = 2419;
|
||||
case Trade = 1481;
|
||||
case TradeAccept = 3863;
|
||||
case TradeCancel = 2341;
|
||||
case TradeClose = 2551;
|
||||
case TradeConfirm = 2760;
|
||||
case TradeItem = 3107;
|
||||
case TradeItemRemove = 3845;
|
||||
case TradeItems = 1263;
|
||||
case TradeUnaccept = 1444;
|
||||
case UnitAction = 2456;
|
||||
case UnitChat = 1314;
|
||||
case UnitChatShout = 2085;
|
||||
case UnitChatWhisper = 1543;
|
||||
case UnitDance = 2080;
|
||||
case UnitDropHandItem = 2814;
|
||||
case UnitGiveHanditem = 2941;
|
||||
case UnitLook = 3301;
|
||||
case UnitPosture = 2235;
|
||||
case UnitSign = 1975;
|
||||
case UnitTyping = 1597;
|
||||
case UnitTypingStop = 1474;
|
||||
case UnitWalk = 3320;
|
||||
case UserBadges = 2769;
|
||||
case UserBadgesCurrent = 2091;
|
||||
case UserBadgesCurrentUpdate = 644;
|
||||
case UserBots = 3848;
|
||||
case UserCurrency = 273;
|
||||
case UserEffectActivate = 2959;
|
||||
case UserEffectEnable = 1752;
|
||||
case UserFigure = 2730;
|
||||
case UserFurniture = 3150; // sent when in room
|
||||
case Requestfurniinventorywhennotinroom = 3500; // sent when not in room
|
||||
case UserHomeRoom = 1740;
|
||||
case UserInfo = 357;
|
||||
case UserMotto = 2228;
|
||||
case UserIgnored = 3878;
|
||||
case UserPets = 3095;
|
||||
case UserProfile = 3265;
|
||||
case UserProfileByName = 2249;
|
||||
case UserRespect = 2694;
|
||||
case GetSoundSettings = 2388;
|
||||
case UserSettingsCamera = 1461;
|
||||
case UserSettingsChatStyle = 1030;
|
||||
case UserSettingsInvites = 1086;
|
||||
case UserSettingsOldChat = 1262;
|
||||
case UserSettingsVolume = 1367;
|
||||
case UserSubscription = 3166;
|
||||
case GetWardrobe = 2742;
|
||||
case SaveWardrobeOutfit = 800;
|
||||
case UserTags = 17;
|
||||
case PeerUsersClassification = 1160;
|
||||
case UserClassification = 2285;
|
||||
case VisitUser = 2970;
|
||||
case WiredActionSave = 2281;
|
||||
case WiredApplySnapshot = 3373;
|
||||
case WiredConditionSave = 3203;
|
||||
case WiredOpen = 768;
|
||||
case WiredTriggerSave = 1520;
|
||||
case GetItemData = 3964;
|
||||
case OneWayDoorClick = 2765;
|
||||
case RemoveWallItem = 3336;
|
||||
case SetItemData = 3666;
|
||||
case CatalogRedeemVoucher = 339;
|
||||
case RoomTonerApply = 2880;
|
||||
case FriendFurniConfirmLock = 3775;
|
||||
case MannequinSaveName = 2850;
|
||||
case MannequinSaveLook = 2209;
|
||||
case PresentOpenPresent = 3558;
|
||||
case CatalogSelectVipGift = 2276;
|
||||
case UserIgnoreId = 3314;
|
||||
case UserIgnore = 1117;
|
||||
case UserUnignore = 2061;
|
||||
case ModtoolRequestRoomInfo = 707;
|
||||
case ModtoolChangeRoomSettings = 3260;
|
||||
case ModtoolRequestUserChatlog = 1391;
|
||||
case ModtoolRequestRoomChatlog = 2587;
|
||||
case ModtoolSanctionAlert = 229;
|
||||
case ModtoolSanctionBan = 2766;
|
||||
case ModtoolSanctionKick = 2582;
|
||||
case ModtoolSanctionTradelock = 3742;
|
||||
case ModtoolAlertevent = 1840;
|
||||
case ModtoolSanctionMute = 1945;
|
||||
case ModtoolRequestUserRooms = 3526;
|
||||
case ModtoolRoomAlert = 3842;
|
||||
case ModtoolPreferences = 31;
|
||||
case CloseIssueDefaultAction = 2717;
|
||||
case CloseIssues = 2067;
|
||||
case DefaultSanction = 1681;
|
||||
case GetCfhChatlog = 211;
|
||||
case ModtoolSanction = 1392;
|
||||
case PickIssues = 15;
|
||||
case ReleaseIssues = 1572;
|
||||
case ConvertGlobalRoomId = 314;
|
||||
case RequestSellItem = 848;
|
||||
case RequestMarketplaceItemStats = 3288;
|
||||
case MarketplaceSellItem = 3447;
|
||||
case MarketplaceRequestOwnItems = 2105;
|
||||
case MarketplaceTakeBackItem = 434;
|
||||
case MarketplaceRedeemCredits = 2650;
|
||||
case MarketplaceRequestOffers = 2407;
|
||||
case MarketplaceBuyOffer = 1603;
|
||||
case MarketplaceBuyTokens = 1866;
|
||||
case CatalogRequesetPetBreeds = 1756;
|
||||
case ApproveName = 2109;
|
||||
case UnitGiveHanditemPet = 2768;
|
||||
case PetSupplement = 749;
|
||||
case FurnitureGroupInfo = 2651;
|
||||
case AchievementResolutionOpen = 359;
|
||||
case UsePetProduct = 1328;
|
||||
case RemovePetSaddle = 186;
|
||||
case TogglePetRiding = 1472;
|
||||
case TogglePetBreeding = 3379;
|
||||
case UnseenResetCategory = 3493;
|
||||
case UnseenResetItems = 2343;
|
||||
case CommunityGoalVoteComposer = 3536;
|
||||
case GetPromoArticles = 1827;
|
||||
case AcceptQuest = 3604;
|
||||
case ActivateQuest = 793;
|
||||
case CancelQuest = 3133;
|
||||
case FriendRequestQuestComplete = 1148;
|
||||
case GetCommunityGoalEarnedPrizes = 2688;
|
||||
case GetCommunityGoalHallOfFame = 2167;
|
||||
case GetCommunityGoalProgress = 1145;
|
||||
case GetConcurrentUsersGoalProgress = 1343;
|
||||
case GetConcurrentUsersReward = 3872;
|
||||
case GetDailyQuest = 2486;
|
||||
case GetQuests = 3333;
|
||||
case GetSeasonalQuestsOnly = 1190;
|
||||
case OpenQuestTracker = 2750;
|
||||
case RedeemCommunityGoalPrize = 90;
|
||||
case RejectQuest = 2397;
|
||||
case StartCampaign = 1697;
|
||||
case GetBonusRareInfo = 957;
|
||||
case Craft = 3591;
|
||||
case CraftSecret = 1251;
|
||||
case GetCraftableProducts = 633;
|
||||
case GetCraftingRecipe = 1173;
|
||||
case GetCraftingRecipesAvailable = 3086;
|
||||
case PhotoCompetition = 3959;
|
||||
case PublishPhoto = 2068;
|
||||
case PurchasePhoto = 2408;
|
||||
case RenderRoom = 3226;
|
||||
case RenderRoomThumbnail = 1982;
|
||||
case RequestCameraConfiguration = 796;
|
||||
case AddJukeboxDisk = 753;
|
||||
case GetJukeboxPlaylist = 1435;
|
||||
case GetNowPlaying = 1325;
|
||||
case GetOfficialSongId = 3189;
|
||||
case GetSongInfo = 3082;
|
||||
case GetSoundMachinePlaylist = 3498;
|
||||
case GetUserSongDisks = 2304;
|
||||
case RemoveJukeboxDisk = 3050;
|
||||
case InterstitialShown = 1109;
|
||||
case GetInterstitial = 2519;
|
||||
case ChangeUsername = 2977;
|
||||
case CheckUsername = 3950;
|
||||
case OpenCampaignCalendarDoorStaff = 3889;
|
||||
case OpenCampaignCalendarDoor = 2257;
|
||||
case BuildersClubPlaceRoomItem = 1051;
|
||||
case BuildersClubPlaceWallItem = 462;
|
||||
case BuildersClubQueryFurniCount = 2529;
|
||||
case GetCatalogPageExpiration = 742;
|
||||
case GetCatalogPageWithEarliestExp = 3135;
|
||||
case GetDirectClubBuyAvailable = 801;
|
||||
case GetHabboBasicMembershipExtendOffer = 603;
|
||||
case GetHabboClubExtendOffer = 2462;
|
||||
case GetIsOfferGiftable = 1347;
|
||||
case GetLimitedOfferAppearingNext = 410;
|
||||
case GetNextTargetedOffer = 596;
|
||||
case GetRoomAdPurchaseInfo = 1075;
|
||||
case GetSeasonalCalendarDailyOffer = 3257;
|
||||
case GetTargetedOffer = 2487;
|
||||
case MarkCatalogNewAdditionsPageOpened = 2150;
|
||||
case PurchaseBasicMembershipExtension = 2735;
|
||||
case PurchaseRoomAd = 777;
|
||||
case PurchaseTargetedOffer = 1826;
|
||||
case PurchaseVipMembershipExtension = 3407;
|
||||
case RoomAdPurchaseInitiated = 2283;
|
||||
case SetTargettedOfferState = 2041;
|
||||
case ShopTargetedOfferViewed = 3483;
|
||||
case HelperTalentTrack = 196;
|
||||
case TalentTrackGetLevel = 2127;
|
||||
case ForwardToACompetitionRoom = 172;
|
||||
case ForwardToASubmittableRoom = 1450;
|
||||
case ForwardToRandomCompetitionRoom = 865;
|
||||
case GetIsUserPartOfCompetition = 2077;
|
||||
case GetSecondsUntil = 271;
|
||||
case RoomCompetitionInit = 1334;
|
||||
case SubmitRoomToCompetition = 2595;
|
||||
case VoteForRoom = 143;
|
||||
case GetGift = 2436;
|
||||
case ResetPhoneNumberState = 2741;
|
||||
case SetPhoneNumberVerificationStatus = 1379;
|
||||
case TryPhoneNumber = 790;
|
||||
case VerifyCode = 2721;
|
||||
case ControlYoutubeDisplayPlayback = 3005;
|
||||
case GetYoutubeDisplayStatus = 336;
|
||||
case SetYoutubeDisplayPlaylist = 2069;
|
||||
case GoToFlat = 685;
|
||||
case ChangeQueue = 3093;
|
||||
case CallForHelpFromForumMessage = 1412;
|
||||
case CallForHelpFromForumThread = 534;
|
||||
case CallForHelpFromIm = 2950;
|
||||
case CallForHelpFromPhoto = 2492;
|
||||
case CallForHelpFromSelfie = 2755;
|
||||
case ChatReviewGuideDecides = 3365;
|
||||
case ChatReviewGuideDetached = 2501;
|
||||
case ChatReviewGuideVote = 3961;
|
||||
case ChatReviewSessionCreate = 3060;
|
||||
case DeletePendingCallsForHelp = 3605;
|
||||
case GetCfhStatus = 2746;
|
||||
case GetFaqCategory = 3445;
|
||||
case GetFaqText = 1849;
|
||||
case GetGuideReportingStatus = 3786;
|
||||
case GetPendingCallsForHelp = 3267;
|
||||
case GetQuizQuestions = 1296;
|
||||
case GuideSessionCreate = 3338;
|
||||
case GuideSessionFeedback = 477;
|
||||
case GuideSessionGetRequesterRoom = 1052;
|
||||
case GuideSessionGuideDecides = 1424;
|
||||
case GuideSessionInviteRequester = 234;
|
||||
case GuideSessionIsTyping = 519;
|
||||
case GuideSessionMessage = 3899;
|
||||
case GuideSessionOnDutyUpdate = 1922;
|
||||
case GuideSessionReport = 3969;
|
||||
case GuideSessionRequesterCancels = 291;
|
||||
case GuideSessionResolved = 887;
|
||||
case PostQuizAnswers = 3720;
|
||||
case SearchFaqs = 2031;
|
||||
case PollAnswer = 3505;
|
||||
case PollReject = 1773;
|
||||
case PollStart = 109;
|
||||
case PollVoteCounter = 6200;
|
||||
case Disconnect = 2445;
|
||||
case ScrGetKickbackInfo = 869;
|
||||
case CompostPlant = 3835;
|
||||
case HarvestPet = 1521;
|
||||
case SetClothingChangeData = 924;
|
||||
case GroupUnfavorite = 1820;
|
||||
case NewUserExperienceGetGifts = 1822;
|
||||
case NewUserExperienceScriptProceed = 1299;
|
||||
case HandshakeInitDiffie = 3110;
|
||||
case HandshakeCompleteDiffie = 773;
|
||||
case WelcomeOpenGift = 2638;
|
||||
case WelcomeGiftChangeEmail = 66;
|
||||
case EmailGetStatus = 2557;
|
||||
case EmailChange = 3965;
|
||||
case ApproveAllMembershipRequests = 882;
|
||||
case RentableSpaceCancelRent = 1667;
|
||||
case RentableSpaceRent = 2946;
|
||||
case RentableSpaceStatus = 872;
|
||||
case TrackingPerformanceLog = 3230;
|
||||
case TrackingLagWarningReport = 3847;
|
||||
case RoomDirectoryRoomNetworkOpenConnection = 3736;
|
||||
case RentableExtendRentOrBuyoutStripItem = 2115;
|
||||
case RentableExtendRentOrBuyoutFurni = 1071;
|
||||
case RentableGetRentOrBuyoutOffer = 2518;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Incoming;
|
||||
|
||||
use Emulator\Network\Game\Sessions\Session;
|
||||
|
||||
interface IMessageEvent {
|
||||
function handle(Session $session, ClientMessage $clientMessage): void;
|
||||
function getHeader(): Header;
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages;
|
||||
|
||||
use Emulator\Core\Logging\Logger;
|
||||
use Emulator\Messages\Incoming\ClientMessage;
|
||||
use Emulator\Messages\Incoming\Handshake\ReleaseVersionMessageEvent;
|
||||
use Emulator\Messages\Incoming\Handshake\SecurityTicketMessageEvent;
|
||||
use Emulator\Messages\Incoming\Header;
|
||||
use Emulator\Network\Game\Sessions\Session;
|
||||
use SplObjectStorage;
|
||||
|
||||
class MessageHandler {
|
||||
private static ?MessageHandler $instance = null;
|
||||
private SplObjectStorage $handlers;
|
||||
|
||||
public function __construct() {
|
||||
$this->handlers = new SplObjectStorage();
|
||||
$this->handlers[Header::ReleaseVersion] = new ReleaseVersionMessageEvent();
|
||||
$this->handlers[Header::SecurityTicket] = new SecurityTicketMessageEvent();
|
||||
}
|
||||
|
||||
public function handlePacket(Session $session, ClientMessage $request): void {
|
||||
if (($header = Header::tryFrom($request->getHeader()))) {
|
||||
if ($this->handlers->contains($header)) {
|
||||
$this->handlers[$header]->handle($session, $request);
|
||||
} else {
|
||||
Logger::warn("[{$request->getHeader()}] [$header->name] - Unregistered!");
|
||||
}
|
||||
} else {
|
||||
Logger::warn("[{$request->getHeader()}] - Unregistered!");
|
||||
}
|
||||
}
|
||||
|
||||
public static function getInstance(): MessageHandler {
|
||||
if (self::$instance === null)
|
||||
self::$instance = new self();
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Outgoing\Handshake;
|
||||
|
||||
use Emulator\Messages\Outgoing\Header;
|
||||
use Emulator\Messages\Outgoing\IMessageComposer;
|
||||
use Emulator\Messages\Outgoing\ServerMessage;
|
||||
use Override;
|
||||
|
||||
class AuthenticatedComposer implements IMessageComposer
|
||||
{
|
||||
|
||||
#[Override] function compose(ServerMessage $message): void {
|
||||
}
|
||||
|
||||
#[Override] function getHeader(): Header {
|
||||
return Header::Authenticated;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,467 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Outgoing;
|
||||
|
||||
enum Header : int {
|
||||
case AchievementList = 305;
|
||||
case Authenticated = 2491;
|
||||
case Authentication = -1;
|
||||
case AvailabilityStatus = 2033;
|
||||
case ClubOffers = 2405;
|
||||
case CatalogPage = 804;
|
||||
case CatalogPageList = 1032;
|
||||
case CatalogPurchaseOk = 869;
|
||||
case CatalogPurchaseError = 1404;
|
||||
case CatalogPurchaseNotAllowed = 3770;
|
||||
case ProductOffer = 3388;
|
||||
case LimitedSoldOut = 377;
|
||||
case CatalogPublished = 1866;
|
||||
case CfhResultMessage = 3635;
|
||||
case ClientLatency = 10;
|
||||
case ClientPing = 3928;
|
||||
case DesktopView = 122;
|
||||
case BundleDiscountRuleset = 2347;
|
||||
case FirstLoginOfDay = 793;
|
||||
case FurnitureAliases = 1723;
|
||||
case FurnitureData = 2547;
|
||||
case FurnitureFloor = 1778;
|
||||
case FurnitureFloorAdd = 1534;
|
||||
case FurnitureFloorRemove = 2703;
|
||||
case FurnitureFloorUpdate = 3776;
|
||||
case FurnitureItemdata = 2202;
|
||||
case FurnitureState = 2376;
|
||||
case FurnitureGroupContextMenuInfo = 3293;
|
||||
case FurniturePostitStickyPoleOpen = 2366;
|
||||
case GameCenterAchievements = 2265;
|
||||
case GameCenterGameList = 222;
|
||||
case GameCenterStatus = 2893;
|
||||
case GameCenterInArenaQueue = 872;
|
||||
case GameCenterStopCounter = 3191;
|
||||
case GameCenterUserLeftGame = 3138;
|
||||
case GameCenterDirectoryStatus = 2246;
|
||||
case GameCenterStartingGameFailed = 2142;
|
||||
case GameCenterJoiningFailed = 1730;
|
||||
case Gamestatusmessage = 3805;
|
||||
case Gameachievements = 1689;
|
||||
case Gameinvite = 904;
|
||||
case Joiningqueuefailed = 3035;
|
||||
case Joinedqueuemessage = 2260;
|
||||
case Leftqueue = 1477;
|
||||
case LoadGameUrl = 2624;
|
||||
case Loadgame = 3654;
|
||||
case Unloadgame = 1715;
|
||||
case Achievementresolutioncompleted = 740;
|
||||
case Achievementresolutionprogress = 3370;
|
||||
case Achievementresolutions = 66;
|
||||
case GenericAlert = 3801;
|
||||
case ModeratorMessage = 2030;
|
||||
case GenericError = 1600;
|
||||
case GiftWrapperConfig = 2234;
|
||||
case GroupBadges = 2402;
|
||||
case GroupCreateOptions = 2159;
|
||||
case GroupForumData = 3011;
|
||||
case GroupForumList = 3001;
|
||||
case GroupForumThreads = 1073;
|
||||
case GroupForumPost = 2049;
|
||||
case GroupForumPostThread = 1862;
|
||||
case GroupForumThreadMessages = 509;
|
||||
case GroupForumUnreadCount = 2379;
|
||||
case GroupForumUpdateMessage = 324;
|
||||
case GroupForumUpdateThread = 2528;
|
||||
case GroupInfo = 1702;
|
||||
case GroupList = 420;
|
||||
case GroupMember = 265;
|
||||
case GroupMembers = 1200;
|
||||
case GroupMembersRefresh = 2445;
|
||||
case GroupMemberRemoveConfirm = 1876;
|
||||
case GroupPurchased = 2808;
|
||||
case GroupSettings = 3965;
|
||||
case GroupBadgeParts = 2238;
|
||||
case GroupMembershipRequested = 1180;
|
||||
case GroupDetailsChanged = 1459;
|
||||
case GroupHabboJoinFailed = 762;
|
||||
case GuildEditFailed = 3988;
|
||||
case GuildMemberMgmtFailed = 818;
|
||||
case ItemDimmerSettings = 2710;
|
||||
case ItemStackHelper = 2816;
|
||||
case ItemWall = 1369;
|
||||
case ItemWallAdd = 2187;
|
||||
case ItemWallRemove = 3208;
|
||||
case ItemWallUpdate = 2009;
|
||||
case MarketplaceConfig = 1823;
|
||||
case MessengerAcceptFriends = 896;
|
||||
case MessengerChat = 1587;
|
||||
case MessengerFindFriends = 1210;
|
||||
case MessengerFollowFailed = 3048;
|
||||
case MessengerFriendNotification = 3082;
|
||||
case MessengerFriends = 3130;
|
||||
case MessengerInit = 1605;
|
||||
case MessengerInstanceMessageError = 3359;
|
||||
case MessengerInvite = 3870;
|
||||
case MessengerInviteError = 462;
|
||||
case MessengerMinimailCount = 2803;
|
||||
case MessengerMinimailNew = 1911;
|
||||
case MessengerRelationships = 2016;
|
||||
case MessengerRequest = 2219;
|
||||
case MessengerRequestError = 892;
|
||||
case MessengerRequests = 280;
|
||||
case MessengerSearch = 973;
|
||||
case MessengerUpdate = 2800;
|
||||
case ModerationTool = 2696;
|
||||
case ModerationUserInfo = 2866;
|
||||
case MotdMessages = 2035;
|
||||
case NavigatorCategories = 1562;
|
||||
case NavigatorCollapsed = 1543;
|
||||
case NavigatorEventCategories = 3244;
|
||||
case NavigatorLifted = 3104;
|
||||
case NavigatorMetadata = 3052;
|
||||
case NavigatorOpenRoomCreator = 2064;
|
||||
case NavigatorSearch = 2690;
|
||||
case NavigatorSearches = 3984;
|
||||
case NavigatorSettings = 518;
|
||||
case ThumbnailUpdateResult = 1927;
|
||||
case CanCreateRoom = 378;
|
||||
case CategoriesWithVisitorCount = 1455;
|
||||
case CompetitionRoomsData = 3954;
|
||||
case ConvertedRoomId = 1331;
|
||||
case GuestRoomSearchResult = 52;
|
||||
case NotificationList = 1992;
|
||||
case NotificationOfferRewardDelivered = 2125;
|
||||
case NotificationSimpleAlert = 5100;
|
||||
case NotificationElementPointer = 1787;
|
||||
case PetFigureUpdate = 1924;
|
||||
case PetInfo = 2901;
|
||||
case PetTrainingPanel = 1164;
|
||||
case PetLevelUpdate = 2824;
|
||||
case PetScratchFailed = 1130;
|
||||
case PetOpenPackageRequested = 2380;
|
||||
case PetOpenPackageResult = 546;
|
||||
case PetBreeding = 1746;
|
||||
case PetConfirmBreedingResult = 1625;
|
||||
case PetGoToBreedingNestFailure = 2621;
|
||||
case PetNestBreedingSuccess = 2527;
|
||||
case PetConfirmBreedingRequest = 634;
|
||||
case PetBreedingResult = 1553;
|
||||
case RecyclerPrizes = 3164;
|
||||
case RecyclerStatus = 3433;
|
||||
case RecyclerFinished = 468;
|
||||
case RoomBanList = 1869;
|
||||
case RoomBanRemove = 3429;
|
||||
case RoomCreated = 1304;
|
||||
case RoomDoorbell = 2309;
|
||||
case RoomDoorbellAccepted = 3783;
|
||||
case RoomDoorbellRejected = 878;
|
||||
case RoomEnter = 758;
|
||||
case RoomEnterError = 899;
|
||||
case RoomForward = 160;
|
||||
case RoomHeightMap = 2753;
|
||||
case RoomHeightMapUpdate = 558;
|
||||
case RoomInfo = 687;
|
||||
case RoomInfoOwner = 749;
|
||||
case RoomModel = 1301;
|
||||
case RoomModelBlockedTiles = 3990;
|
||||
case RoomModelDoor = 1664;
|
||||
case RoomModelName = 2031;
|
||||
case RoomMuted = 2533;
|
||||
case RoomPaint = 2454;
|
||||
case RoomPromotion = 2274;
|
||||
case RoomQueueStatus = 2208;
|
||||
case RoomRights = 780;
|
||||
case RoomRightsClear = 2392;
|
||||
case RoomRightsList = 1284;
|
||||
case RoomRightsListAdd = 2088;
|
||||
case RoomRightsListRemove = 1327;
|
||||
case RoomRightsOwner = 339;
|
||||
case RoomRolling = 3207;
|
||||
case RoomScore = 482;
|
||||
case RoomSettings = 1498;
|
||||
case RoomSettingsChat = 1191;
|
||||
case RoomSettingsSave = 948;
|
||||
case RoomSettingsSaveError = 1555;
|
||||
case RoomInfoUpdated = 3297;
|
||||
case RoomSpectator = 1033;
|
||||
case RoomThickness = 3547;
|
||||
case RoomGetFilterWords = 2937;
|
||||
case RoomMessageNotification = 1634;
|
||||
case RoomPopularTagsResult = 2012;
|
||||
case InfoFeedEnable = 3284;
|
||||
case SecurityMachine = 1488;
|
||||
case MysteryBoxKeys = 2833;
|
||||
case Gotmysteryboxprizemessage = 3712;
|
||||
case Cancelmysteryboxwaitmessage = 596;
|
||||
case Showmysteryboxwaitmessage = 3201;
|
||||
case TradeAccepted = 2568;
|
||||
case TradeClosed = 1373;
|
||||
case TradeCompleted = 1001;
|
||||
case TradeConfirmation = 2720;
|
||||
case TradeListItem = 2024;
|
||||
case TradeNotOpen = 3128;
|
||||
case TradeOpen = 2505;
|
||||
case TradeOpenFailed = 217;
|
||||
case TradeOtherNotAllowed = 1254;
|
||||
case TradeYouNotAllowed = 3058;
|
||||
case TradeNoSuchItem = 2873;
|
||||
case Unit = 374;
|
||||
case UnitChangeName = 2182;
|
||||
case UnitChat = 1446;
|
||||
case UnitChatShout = 1036;
|
||||
case UnitChatWhisper = 2704;
|
||||
case UnitDance = 2233;
|
||||
case UnitEffect = 1167;
|
||||
case UnitExpression = 1631;
|
||||
case UnitHandItem = 1474;
|
||||
case UnitIdle = 1797;
|
||||
case UnitInfo = 3920;
|
||||
case UnitNumber = 2324;
|
||||
case UnitRemove = 2661;
|
||||
case UnitStatus = 1640;
|
||||
case UnitTyping = 1717;
|
||||
case UnseenItems = 2103;
|
||||
case UserAchievementScore = 1968;
|
||||
case UserBadges = 717;
|
||||
case UserBadgesAdd = 2493;
|
||||
case UserBadgesCurrent = 1087;
|
||||
case UserBots = 3086;
|
||||
case UserChangeName = 118;
|
||||
case UserClothing = 1450;
|
||||
case UserCredits = 3475;
|
||||
case UserCurrency = 2018;
|
||||
case ActivityPointNotification = 2275;
|
||||
case UserFavoriteRoom = 2524;
|
||||
case UserFavoriteRoomCount = 151;
|
||||
case UserFigure = 2429;
|
||||
case UserFurniture = 994;
|
||||
case UserFurnitureAdd = 104;
|
||||
case UserFurniturePostitPlaced = 1501;
|
||||
case UserFurnitureRefresh = 3151;
|
||||
case UserFurnitureRemove = 159;
|
||||
case UserHomeRoom = 2875;
|
||||
case RoomEventCancel = 3479;
|
||||
case RoomEvent = 1840;
|
||||
case UserIgnored = 126;
|
||||
case UserIgnoredResult = 207;
|
||||
case UserInfo = 2725;
|
||||
case UserPerks = 2586;
|
||||
case UserPermissions = 411;
|
||||
case UserPetAdd = 2101;
|
||||
case UserPetRemove = 3253;
|
||||
case UserPets = 3522;
|
||||
case UserProfile = 3898;
|
||||
case UserRespect = 2815;
|
||||
case UserSanctionStatus = 3679;
|
||||
case UserSettings = 513;
|
||||
case UserSubscription = 954;
|
||||
case UserWardrobePage = 3315;
|
||||
case UserClassification = 966;
|
||||
case GetUserTags = 1255;
|
||||
case WiredAction = 1434;
|
||||
case WiredCondition = 1108;
|
||||
case WiredError = 156;
|
||||
case WiredOpen = 1830;
|
||||
case WiredReward = 178;
|
||||
case WiredSave = 1155;
|
||||
case WiredTrigger = 383;
|
||||
case PlayingGame = 448;
|
||||
case FurnitureState2 = 3431;
|
||||
case RemoveBotFromInventory = 233;
|
||||
case AddBotToInventory = 1352;
|
||||
case AchievementProgressed = 2107;
|
||||
case ModtoolRoomInfo = 1333;
|
||||
case ModtoolUserChatlog = 3377;
|
||||
case ModtoolRoomChatlog = 3434;
|
||||
case ModtoolVisitedRoomsUser = 1752;
|
||||
case ModeratorActionResult = 2335;
|
||||
case IssueDeleted = 3192;
|
||||
case IssueInfo = 3609;
|
||||
case IssuePickFailed = 3150;
|
||||
case CfhChatlog = 607;
|
||||
case ModeratorToolPreferences = 1576;
|
||||
case LovelockFurniStart = 3753;
|
||||
case LovelockFurniFriendComfirmed = 382;
|
||||
case LovelockFurniFinished = 770;
|
||||
case GiftReceiverNotFound = 1517;
|
||||
case GiftOpened = 56;
|
||||
case FloodControl = 566;
|
||||
case RemainingMute = 826;
|
||||
case UserEffectList = 340;
|
||||
case UserEffectListAdd = 2867;
|
||||
case UserEffectListRemove = 2228;
|
||||
case UserEffectActivate = 1959;
|
||||
case AvatarEffectSelected = 3473;
|
||||
case ClubGiftInfo = 619;
|
||||
case RedeemVoucherError = 714;
|
||||
case RedeemVoucherOk = 3336;
|
||||
case InClientLink = 2023;
|
||||
case BotCommandConfiguration = 1618;
|
||||
case BotSkillListUpdate = 69;
|
||||
case BotForceOpenContextMenu = 296;
|
||||
case HandItemReceived = 354;
|
||||
case PetPlacingError = 2913;
|
||||
case BotError = 639;
|
||||
case MarketplaceSellItem = 54;
|
||||
case MarketplaceItemStats = 725;
|
||||
case MarketplaceOwnItems = 3884;
|
||||
case MarketplaceCancelSale = 3264;
|
||||
case MarketplaceItemPosted = 1359;
|
||||
case MarketplaceItemsSearched = 680;
|
||||
case MarketplaceAfterOrderStatus = 2032;
|
||||
case CatalogReceivePetBreeds = 3331;
|
||||
case CatalogApproveNameResult = 1503;
|
||||
case ObjectsDataUpdate = 1453;
|
||||
case PetExperience = 2156;
|
||||
case CommunityGoalVoteEvent = 1435;
|
||||
case PromoArticles = 286;
|
||||
case CommunityGoalEarnedPrizes = 3319;
|
||||
case CommunityGoalProgress = 2525;
|
||||
case ConcurrentUsersGoalProgress = 2737;
|
||||
case QuestDaily = 1878;
|
||||
case QuestCancelled = 3027;
|
||||
case QuestCompleted = 949;
|
||||
case CommunityGoalHallOfFame = 3005;
|
||||
case EpicPopup = 3945;
|
||||
case SeasonalQuests = 1122;
|
||||
case Quests = 3625;
|
||||
case Quest = 230;
|
||||
case BonusRareInfo = 1533;
|
||||
case CraftableProducts = 1000;
|
||||
case CraftingRecipe = 2774;
|
||||
case CraftingRecipesAvailable = 2124;
|
||||
case CraftingResult = 618;
|
||||
case CameraPublishStatus = 2057;
|
||||
case CameraPurchaseOk = 2783;
|
||||
case CameraStorageUrl = 3696;
|
||||
case CameraSnapshot = 463;
|
||||
case CompetitionStatus = 133;
|
||||
case InitCamera = 3878;
|
||||
case ThumbnailStatus = 3595;
|
||||
case AchievementNotification = 806;
|
||||
case ClubGiftNotification = 2188;
|
||||
case InterstitialMessage = 1808;
|
||||
case RoomAdError = 1759;
|
||||
case AvailabilityTime = 600;
|
||||
case HotelClosedAndOpens = 3728;
|
||||
case HotelClosesAndOpensAt = 2771;
|
||||
case HotelWillCloseMinutes = 1050;
|
||||
case HotelMaintenance = 1350;
|
||||
case JukeboxPlaylistFull = 105;
|
||||
case JukeboxSongDisks = 34;
|
||||
case NowPlaying = 469;
|
||||
case OfficialSongId = 1381;
|
||||
case Playlist = 1748;
|
||||
case PlaylistSongAdded = 1140;
|
||||
case TraxSongInfo = 3365;
|
||||
case UserSongDisksInventory = 2602;
|
||||
case CheckUserName = 563;
|
||||
case CfhSanction = 2782;
|
||||
case CfhTopics = 325;
|
||||
case CfhSanctionStatus = 2221;
|
||||
case CampaignCalendarData = 2531;
|
||||
case CampaignCalendarDoorOpened = 2551;
|
||||
case BuildersClubFurniCount = 3828;
|
||||
case BuildersClubSubscription = 1452;
|
||||
case CatalogPageExpiration = 2668;
|
||||
case CatalogEarliestExpiry = 2515;
|
||||
case ClubGiftSelected = 659;
|
||||
case TargetOfferNotFound = 1237;
|
||||
case TargetOffer = 119;
|
||||
case DirectSmsClubBuy = 195;
|
||||
case RoomAdPurchase = 2468;
|
||||
case NotEnoughBalance = 3914;
|
||||
case LimitedOfferAppearingNext = 44;
|
||||
case IsOfferGiftable = 761;
|
||||
case ClubExtendedOffer = 3964;
|
||||
case SeasonalCalendarOffer = 1889;
|
||||
case CompetitionEntrySubmit = 1177;
|
||||
case CompetitionVotingInfo = 3506;
|
||||
case CompetitionTimingCode = 1745;
|
||||
case CompetitionUserPartOf = 3841;
|
||||
//case CompetitionNoOwnedRooms = 2064;
|
||||
case CompetitionSecondsUntil = 3926;
|
||||
case BadgePointLimits = 2501;
|
||||
case BadgeRequestFulfilled = 2998;
|
||||
case HelperTalentTrack = 3406;
|
||||
case TalentTrackLevel = 1203;
|
||||
case TalentTrackLevelUp = 638;
|
||||
case UserBanned = 1683;
|
||||
case BotReceived = 3684;
|
||||
case PetLevelNotification = 859;
|
||||
case PetReceived = 1111;
|
||||
case ModerationCaution = 1890;
|
||||
case YoutubeControlVideo = 1554;
|
||||
case YoutubeDisplayPlaylists = 1112;
|
||||
case YoutubeDisplayVideo = 1411;
|
||||
case CfhDisabledNotify = 1651;
|
||||
case Question = 2665;
|
||||
case PollContents = 2997;
|
||||
case PollError = 662;
|
||||
case PollOffer = 3785;
|
||||
case PollRoomResult = 5201;
|
||||
case PollStartRoom = 5200;
|
||||
case QuestionAnswered = 2589;
|
||||
case QuestionFinished = 1066;
|
||||
case CfhPendingCalls = 1121;
|
||||
case GuideOnDutyStatus = 1548;
|
||||
case GuideSessionAttached = 1591;
|
||||
case GuideSessionDetached = 138;
|
||||
case GuideSessionEnded = 1456;
|
||||
case GuideSessionError = 673;
|
||||
case GuideSessionInvitedToGuideRoom = 219;
|
||||
case GuideSessionMessage = 841;
|
||||
case GuideSessionPartnerIsTyping = 1016;
|
||||
case GuideSessionRequesterRoom = 1847;
|
||||
case GuideSessionStarted = 3209;
|
||||
case GuideTicketCreationResult = 3285;
|
||||
case GuideTicketResolution = 2674;
|
||||
case GuideReportingStatus = 3463;
|
||||
case HotelMergeNameChange = 1663;
|
||||
case IssueCloseNotification = 934;
|
||||
case QuizData = 2927;
|
||||
case QuizResults = 2772;
|
||||
case CfhPendingCallsDeleted = 77;
|
||||
case CfhReply = 3796;
|
||||
case ChatReviewSessionDetached = 30;
|
||||
case ChatReviewSessionOfferedToGuide = 735;
|
||||
case ChatReviewSessionResults = 3276;
|
||||
case ChatReviewSessionStarted = 143;
|
||||
case ChatReviewSessionVotingStatus = 1829;
|
||||
case ScrSendKickbackInfo = 3277;
|
||||
case PetStatus = 1907;
|
||||
case GroupDeactivate = 3129;
|
||||
case PetRespected = 2788;
|
||||
case PetSupplement = 3441;
|
||||
case NoobnessLevel = 3738;
|
||||
case DisconnectReason = 4000;
|
||||
case CanCreateRoomEvent = 2599;
|
||||
case FavoriteGroupUdpate = 3403;
|
||||
case NoSuchFlat = 84;
|
||||
case RoomSettingsError = 2897;
|
||||
case ShowEnforceRoomCategory = 3896;
|
||||
case CustomUserNotification = 909;
|
||||
case NewUserExperienceGiftOffer = 3575;
|
||||
case RestoreClient = 426;
|
||||
case FireworkChargeData = 5210;
|
||||
case NewUserExperienceNotComplete = 3639;
|
||||
case ConnectionError = 1004;
|
||||
case AccountSafetyLockStatusChange = 1243;
|
||||
case PhoneCollectionState = 2890;
|
||||
case PhoneTryNumberResult = 800;
|
||||
case PhoneTryVerificationCodeResult = 91;
|
||||
case ExtendedProfileChanged = 876;
|
||||
case WelcomeGiftChangeEmailResult = 2293;
|
||||
case WelcomeGiftStatus = 2707;
|
||||
case HandshakeInitDiffie = 1347;
|
||||
case HandshakeCompleteDiffie = 3885;
|
||||
case RentableSpaceRentOk = 2046;
|
||||
case RentableSpaceStatus = 3559;
|
||||
case RentableSpaceRentFailed = 1868;
|
||||
case EmailStatus = 612;
|
||||
case ChangeEmailResult = 1815;
|
||||
case WeeklyGameReward = 2641;
|
||||
case WeeklyGameRewardWinners = 3097;
|
||||
case WeeklyCompetitiveLeaderboard = 3512;
|
||||
case WeeklyCompetitiveFriendsLeaderboard = 3560;
|
||||
case WeeklyGame2FriendsLeaderboard = 2270;
|
||||
case WeeklyGame2Leaderboard = 2196;
|
||||
case RentableFurniRentOrBuyoutOffer = 35;
|
||||
case HandshakeIdentityAccount = 3523;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Outgoing;
|
||||
|
||||
interface IMessageComposer {
|
||||
function compose(ServerMessage $message): void;
|
||||
function getHeader(): Header;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Messages\Outgoing;
|
||||
|
||||
use Emulator\Encoding\ByteEncoding;
|
||||
|
||||
class ServerMessage {
|
||||
private array $packet = [];
|
||||
|
||||
function __construct(int $header) {
|
||||
$this->writeInt16($header);
|
||||
}
|
||||
|
||||
public function writeInt16(int $value): void {
|
||||
$this->packet = array_merge($this->packet, ByteEncoding::int16ToArray($value));
|
||||
}
|
||||
|
||||
public function writeInt32(int $value): void {
|
||||
$this->packet = array_merge($this->packet, ByteEncoding::int32ToArray($value));
|
||||
}
|
||||
|
||||
public function writeBoolean(bool $value): void {
|
||||
$this->packet[] = ($value ? 1 : 0);
|
||||
}
|
||||
|
||||
public function writeString(string $value): void {
|
||||
$this->writeInt16(strlen($value));
|
||||
$this->packet = array_merge($this->packet, unpack('C*', $value));
|
||||
}
|
||||
|
||||
public function getPacket(): array {
|
||||
return $this->packet;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Network\Game;
|
||||
|
||||
use Emulator\Core\Logging\Logger;
|
||||
use Emulator\Encoding\ByteEncoding;
|
||||
use Emulator\Messages\Incoming\ClientMessage;
|
||||
use Emulator\Messages\MessageHandler;
|
||||
use Emulator\Network\Game\Sessions\Session;
|
||||
use Override;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Ratchet\Http\HttpServer;
|
||||
use Ratchet\RFC6455\Messaging\MessageInterface;
|
||||
use Ratchet\Server\IoServer;
|
||||
use Ratchet\WebSocket\MessageComponentInterface;
|
||||
use Ratchet\WebSocket\WsConnection;
|
||||
use Ratchet\WebSocket\WsServer;
|
||||
use React\EventLoop\Loop;
|
||||
use React\Socket\SocketServer;
|
||||
|
||||
class GameNetworkServer implements MessageComponentInterface {
|
||||
private static ?GameNetworkServer $instance = null;
|
||||
private array $sessions;
|
||||
|
||||
public function start(int $port): void {
|
||||
$loop = Loop::get();
|
||||
|
||||
$this->sessions = [];
|
||||
$socketServer = new SocketServer("127.0.0.1:{$port}", loop: $loop);
|
||||
new IoServer(
|
||||
new HttpServer(
|
||||
new WsServer($this)
|
||||
),
|
||||
$socketServer,
|
||||
$loop
|
||||
);
|
||||
}
|
||||
|
||||
public static function getInstance(): GameNetworkServer {
|
||||
if (self::$instance === null) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
#[Override] function onOpen(ConnectionInterface $conn): void {
|
||||
$this->sessions[$conn->resourceId] = new Session(new WsConnection($conn));
|
||||
}
|
||||
|
||||
#[Override] function onClose(ConnectionInterface $conn): void {
|
||||
unset($this->sessions[$conn->resourceId]);
|
||||
}
|
||||
|
||||
#[Override] function onError(ConnectionInterface $conn, \Exception $e): void {
|
||||
Logger::fatal($e->getMessage());
|
||||
}
|
||||
|
||||
#[Override] public function onMessage(ConnectionInterface $conn, MessageInterface $msg): void {
|
||||
$raw = $msg->getPayload();
|
||||
$data = unpack('C*', $raw);
|
||||
|
||||
if (count($data) >= 6) {
|
||||
$length = ByteEncoding::getInt32(array_slice($data, 1, 4));
|
||||
$packet = array_slice($data, 4, $length);
|
||||
|
||||
MessageHandler::getInstance()->handlePacket($this->sessions[$conn->resourceId], new ClientMessage($packet));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace Emulator\Network\Game\Sessions;
|
||||
|
||||
use Emulator\Encoding\ByteEncoding;
|
||||
use Emulator\Messages\Outgoing\IMessageComposer;
|
||||
use Emulator\Messages\Outgoing\ServerMessage;
|
||||
use Ratchet\RFC6455\Messaging\Frame;
|
||||
use Ratchet\RFC6455\Messaging\Message;
|
||||
use Ratchet\WebSocket\WsConnection;
|
||||
|
||||
readonly class Session {
|
||||
private WsConnection $connection;
|
||||
|
||||
public function __construct(WsConnection $connection) {
|
||||
$this->connection = $connection;
|
||||
}
|
||||
|
||||
public function sendComposer(IMessageComposer $composer): void {
|
||||
$headerData = pack('n', 2491);
|
||||
$length = strlen($headerData);
|
||||
$lengthData = pack('N', $length);
|
||||
$binaryMessage = $lengthData . $headerData;
|
||||
$frame = new Frame($binaryMessage, true, Frame::OP_BINARY);
|
||||
$this->connection->send($frame);
|
||||
}
|
||||
|
||||
function encode($text) {
|
||||
$b1 = 0x80 | (0x1 & 0x0f);
|
||||
$length = strlen($text);
|
||||
if ($length <= 125)
|
||||
$header = pack('CC', $b1, $length);
|
||||
elseif($length > 125 && $length < 65536)
|
||||
$header = pack('CCn', $b1, 126, $length);
|
||||
elseif($length >= 65536)
|
||||
$header = pack('CCNN', $b1, 127, $length);
|
||||
|
||||
return $header.$text;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue