diff --git a/public/ui-config.json.example b/public/ui-config.json.example
index 80b6970a..c9e4a5c3 100644
--- a/public/ui-config.json.example
+++ b/public/ui-config.json.example
@@ -21,6 +21,7 @@
"wired.action.chat.max.length": 100,
"wired.action.kick.from.room.max.length": 100,
"wired.action.mute.user.max.length": 100,
+ "game.center.enabled": false,
"navigator.room.models": [
{ "clubLevel": 0, "tileSize": 104, "name": "a" },
{ "clubLevel": 0, "tileSize": 94, "name": "b" },
diff --git a/src/api/utils/ColorUtils.ts b/src/api/utils/ColorUtils.ts
index 9377255e..100bcc5b 100644
--- a/src/api/utils/ColorUtils.ts
+++ b/src/api/utils/ColorUtils.ts
@@ -23,4 +23,11 @@ export class ColorUtils
{
return parseInt(color.replace('#', ''), 16);
}
+
+ public static uintHexColor(color: number): string
+ {
+ const realColor = color >>>0;
+
+ return ColorUtils.makeColorHex(realColor.toString(16).substring(2));
+ }
}
diff --git a/src/assets/images/gamecenter/selectedIcon.png b/src/assets/images/gamecenter/selectedIcon.png
new file mode 100644
index 00000000..718e48b8
Binary files /dev/null and b/src/assets/images/gamecenter/selectedIcon.png differ
diff --git a/src/assets/styles/icons.scss b/src/assets/styles/icons.scss
index 17c3657f..80ac69d0 100644
--- a/src/assets/styles/icons.scss
+++ b/src/assets/styles/icons.scss
@@ -11,11 +11,11 @@
background-position: center;
&.icon-nitro-light {
- background-image: url('../images/nitro/nitro-n-light.svg');
+ background-image: url("../images/nitro/nitro-n-light.svg");
}
&.icon-nitro-dark {
- background-image: url('../images/nitro/nitro-n-dark.svg');
+ background-image: url("../images/nitro/nitro-n-dark.svg");
}
&.icon-nitro-light,
@@ -25,572 +25,578 @@
}
&.icon-catalog {
- background-image: url('../images/toolbar/icons/catalog.png');
+ background-image: url("../images/toolbar/icons/catalog.png");
width: 37px;
height: 36px;
}
+ &.icon-game {
+ background-image: url("../images/toolbar/icons/game.png");
+ width: 44px;
+ height: 25px;
+ }
+
&.icon-rooms {
- background-image: url('../images/toolbar/icons/rooms.png');
+ background-image: url("../images/toolbar/icons/rooms.png");
width: 44px;
height: 30px;
}
&.icon-house {
- background-image: url('../images/toolbar/icons/house.png');
+ background-image: url("../images/toolbar/icons/house.png");
height: 30px;
width: 32px;
}
&.gray {
- opacity: .5;
+ opacity: 0.5;
}
&.icon-inventory {
- background-image: url('../images/toolbar/icons/inventory.png');
+ background-image: url("../images/toolbar/icons/inventory.png");
height: 41px;
width: 44px;
}
&.icon-modtools {
- background-image: url('../images/toolbar/icons/modtools.png');
+ background-image: url("../images/toolbar/icons/modtools.png");
height: 34px;
width: 29px;
}
&.icon-friendall {
- background-image: url('../images/toolbar/icons/friend_all.png');
+ background-image: url("../images/toolbar/icons/friend_all.png");
height: 33px;
width: 32px;
}
&.icon-friendsearch {
- background-image: url('../images/toolbar/icons/friend_search.png');
+ background-image: url("../images/toolbar/icons/friend_search.png");
height: 33px;
width: 29px;
}
&.icon-sendmessage {
- background-image: url('../images/toolbar/icons/sendmessage.png');
+ background-image: url("../images/toolbar/icons/sendmessage.png");
width: 20px;
height: 21px;
}
&.icon-me-talents {
- background-image: url('../images/toolbar/icons/me-menu/talents.png');
+ background-image: url("../images/toolbar/icons/me-menu/talents.png");
width: 32px;
height: 30px;
}
&.icon-me-helper-tool {
- background-image: url('../images/toolbar/icons/me-menu/helper-tool.png');
+ background-image: url("../images/toolbar/icons/me-menu/helper-tool.png");
width: 32px;
height: 30px;
}
&.icon-me-profile {
- background-image: url('../images/toolbar/icons/me-menu/profile.png');
+ background-image: url("../images/toolbar/icons/me-menu/profile.png");
width: 32px;
height: 30px;
}
&.icon-me-forums {
- background-image: url('../images/toolbar/icons/me-menu/forums.png');
+ background-image: url("../images/toolbar/icons/me-menu/forums.png");
width: 32px;
height: 30px;
}
&.icon-me-rooms {
- background-image: url('../images/toolbar/icons/me-menu/my-rooms.png');
+ background-image: url("../images/toolbar/icons/me-menu/my-rooms.png");
width: 30px;
height: 30px;
}
&.icon-me-achievements {
- background-image: url('../images/toolbar/icons/me-menu/achievements.png');
+ background-image: url("../images/toolbar/icons/me-menu/achievements.png");
width: 31px;
height: 30px;
}
&.icon-me-clothing {
- background-image: url('../images/toolbar/icons/me-menu/clothing.png');
+ background-image: url("../images/toolbar/icons/me-menu/clothing.png");
width: 27px;
height: 30px;
}
&.icon-me-settings {
- background-image: url('../images/toolbar/icons/me-menu/cog.png');
+ background-image: url("../images/toolbar/icons/me-menu/cog.png");
width: 28px;
height: 34px;
}
&.icon-cog {
- background: url('../images/icons/icon_cog.png');
+ background: url("../images/icons/icon_cog.png");
width: 14px;
height: 15px;
}
&.icon-help {
- background: url('../images/icons/help.png');
+ background: url("../images/icons/help.png");
width: 13px;
height: 23px;
}
&.icon-joinroom {
- background-image: url('../images/toolbar/icons/joinroom.png');
+ background-image: url("../images/toolbar/icons/joinroom.png");
width: 21px;
height: 21px;
}
&.icon-habbo {
- background-image: url('../images/toolbar/icons/habbo.png');
+ background-image: url("../images/toolbar/icons/habbo.png");
width: 28px;
height: 28px;
}
&.icon-camera {
- background-image: url('../images/toolbar/icons/camera.png');
+ background-image: url("../images/toolbar/icons/camera.png");
width: 38px;
height: 45px;
}
&.icon-message {
- background-image: url('../images/toolbar/icons/message.png');
+ background-image: url("../images/toolbar/icons/message.png");
width: 36px;
height: 32px;
&.is-unseen {
- background-image: url('../images/toolbar/icons/message_unsee.gif');
+ background-image: url("../images/toolbar/icons/message_unsee.gif");
}
}
&.icon-wired-trigger {
- background-image: url('../images/wired/icon_trigger.png');
+ background-image: url("../images/wired/icon_trigger.png");
width: 13px;
height: 14px;
}
&.icon-wired-condition {
- background-image: url('../images/wired/icon_condition.png');
+ background-image: url("../images/wired/icon_condition.png");
width: 13px;
height: 14px;
}
&.icon-wired-action {
- background-image: url('../images/wired/icon_action.png');
+ background-image: url("../images/wired/icon_action.png");
width: 13px;
height: 14px;
}
&.chatstyles-icon {
- background-image: url('../images/chat/styles-icon.png');
+ background-image: url("../images/chat/styles-icon.png");
width: 17px;
height: 19px;
}
&.pencil-icon {
- background-image: url('../images/infostand/pencil-icon.png');
+ background-image: url("../images/infostand/pencil-icon.png");
width: 17px;
height: 18px;
}
&.trade-locked-icon {
- background-image: url('../images/inventory/trading/locked-icon.png');
+ background-image: url("../images/inventory/trading/locked-icon.png");
width: 29px;
height: 43px;
}
&.trade-unlocked-icon {
- background-image: url('../images/inventory/trading/unlocked-icon.png');
+ background-image: url("../images/inventory/trading/unlocked-icon.png");
width: 29px;
height: 43px;
}
&.modtool-room-icon {
- background-image: url('../images/modtool/room.png');
+ background-image: url("../images/modtool/room.png");
width: 20px;
height: 15px;
}
&.modtool-chatlog-icon {
- background-image: url('../images/modtool/chatlog.gif');
+ background-image: url("../images/modtool/chatlog.gif");
width: 20px;
height: 15px;
}
&.modtool-user-icon {
- background-image: url('../images/modtool/user.gif');
+ background-image: url("../images/modtool/user.gif");
width: 20px;
height: 15px;
}
&.modtool-reports-icon {
- background-image: url('../images/modtool/reports.png');
+ background-image: url("../images/modtool/reports.png");
width: 20px;
height: 15px;
}
&.modtool-wrench-icon {
- background-image: url('../images/modtool/wrench.gif');
+ background-image: url("../images/modtool/wrench.gif");
width: 20px;
height: 15px;
}
&.modtool-key-icon {
- background-image: url('../images/modtool/key.gif');
+ background-image: url("../images/modtool/key.gif");
width: 20px;
height: 15px;
}
&.icon-catalogue-hc_small {
- background-image: url('../images/catalog/hc_small.png');
+ background-image: url("../images/catalog/hc_small.png");
height: 17px;
width: 31px;
}
&.icon-catalogue-hc_big {
- background: url('../images/catalog/hc_big.png');
+ background: url("../images/catalog/hc_big.png");
width: 68px;
height: 40px;
}
&.icon-sign-exclamation {
- background: url('../images/icons/sign-exclamation.png');
+ background: url("../images/icons/sign-exclamation.png");
width: 7px;
height: 17px;
}
&.icon-sign-heart {
- background: url('../images/icons/sign-heart.png');
+ background: url("../images/icons/sign-heart.png");
width: 15px;
height: 13px;
}
&.icon-sign-red {
- background: url('../images/icons/sign-red.png');
+ background: url("../images/icons/sign-red.png");
width: 11px;
height: 19px;
}
&.icon-sign-yellow {
- background: url('../images/icons/sign-yellow.png');
+ background: url("../images/icons/sign-yellow.png");
width: 11px;
height: 19px;
}
&.icon-sign-skull {
- background: url('../images/icons/sign-skull.png');
+ background: url("../images/icons/sign-skull.png");
width: 12px;
height: 12px;
}
&.icon-sign-smile {
- background: url('../images/icons/sign-smile.png');
+ background: url("../images/icons/sign-smile.png");
width: 7px;
height: 14px;
}
&.icon-sign-soccer {
- background: url('../images/icons/sign-soccer.png');
+ background: url("../images/icons/sign-soccer.png");
width: 20px;
height: 20px;
}
&.icon-house-small {
- background: url('../images/icons/house-small.png');
+ background: url("../images/icons/house-small.png");
width: 19px;
height: 14px;
}
&.icon-camera-small {
- background: url('../images/icons/camera-small.png');
+ background: url("../images/icons/camera-small.png");
width: 17px;
height: 15px;
}
&.icon-small-room {
- background: url('../images/icons/small-room.png');
+ background: url("../images/icons/small-room.png");
width: 17px;
height: 16px;
}
&.icon-cog {
- background: url('../images/icons/cog.png');
+ background: url("../images/icons/cog.png");
width: 21px;
height: 21px;
}
&.icon-chat-history {
- background: url('../images/icons/chat-history.png');
+ background: url("../images/icons/chat-history.png");
width: 17px;
height: 21px;
}
&.icon-room-link {
- background: url('../images/icons/room-link.png');
+ background: url("../images/icons/room-link.png");
width: 17px;
height: 15px;
}
&.icon-zoom-more {
- background: url('../images/icons/zoom-more.png');
+ background: url("../images/icons/zoom-more.png");
width: 12px;
height: 22px;
}
&.icon-zoom-less {
- background: url('../images/icons/zoom-less.png');
+ background: url("../images/icons/zoom-less.png");
width: 12px;
height: 22px;
}
&.icon-like-room {
- background: url('../images/icons/like-room.png');
+ background: url("../images/icons/like-room.png");
width: 20px;
height: 22px;
}
&.icon-arrows {
- background: url('../images/icons/arrows.png');
+ background: url("../images/icons/arrows.png");
width: 17px;
height: 15px;
}
&.icon-camera-colormatrix {
- background: url('../images/icons/camera-colormatrix.png');
+ background: url("../images/icons/camera-colormatrix.png");
width: 32px;
height: 21px;
}
&.icon-camera-composite {
- background: url('../images/icons/camera-composite.png');
+ background: url("../images/icons/camera-composite.png");
width: 32px;
height: 21px;
}
&.icon-pf-online {
- background: url('../images/profile/icons/online.gif');
+ background: url("../images/profile/icons/online.gif");
width: 40px;
height: 16px;
}
&.icon-pf-offline {
- background: url('../images/profile/icons/offline.png');
+ background: url("../images/profile/icons/offline.png");
width: 39px;
height: 16px;
}
&.icon-pf-tick {
- background: url('../images/profile/icons/tick.png');
+ background: url("../images/profile/icons/tick.png");
width: 11px;
height: 10px;
}
&.icon-group-type-0 {
- background: url('../images/groups/icons/grouptype_icon_0.png');
+ background: url("../images/groups/icons/grouptype_icon_0.png");
width: 16px;
height: 16px;
}
&.icon-group-type-1 {
- background: url('../images/groups/icons/grouptype_icon_1.png');
+ background: url("../images/groups/icons/grouptype_icon_1.png");
width: 16px;
height: 16px;
}
&.icon-group-type-2 {
- background: url('../images/groups/icons/grouptype_icon_2.png');
+ background: url("../images/groups/icons/grouptype_icon_2.png");
width: 16px;
height: 16px;
}
&.icon-group-decorate {
- background: url('../images/groups/icons/group_decorate_icon.png');
+ background: url("../images/groups/icons/group_decorate_icon.png");
width: 15px;
height: 15px;
}
&.icon-group-member {
- background: url('../images/groups/icons/group_icon_big_member.png');
+ background: url("../images/groups/icons/group_icon_big_member.png");
width: 20px;
height: 20px;
}
&.icon-group-admin {
- background: url('../images/groups/icons/group_icon_big_admin.png');
+ background: url("../images/groups/icons/group_icon_big_admin.png");
width: 20px;
height: 20px;
}
&.icon-group-owner {
- background: url('../images/groups/icons/group_icon_big_owner.png');
+ background: url("../images/groups/icons/group_icon_big_owner.png");
width: 20px;
height: 20px;
}
&.icon-group-favorite {
- background: url('../images/groups/icons/group_favorite.png');
+ background: url("../images/groups/icons/group_favorite.png");
width: 14px;
height: 14px;
}
&.icon-group-not-favorite {
- background: url('../images/groups/icons/group_notfavorite.png');
+ background: url("../images/groups/icons/group_notfavorite.png");
width: 14px;
height: 14px;
}
&.icon-group-small-admin {
- background: url('../images/groups/icons/group_icon_admin.png');
+ background: url("../images/groups/icons/group_icon_admin.png");
width: 11px;
height: 13px;
}
&.icon-group-small-not-admin {
- background: url('../images/groups/icons/group_icon_not_admin.png');
+ background: url("../images/groups/icons/group_icon_not_admin.png");
width: 11px;
height: 13px;
}
&.icon-group-small-owner {
- background: url('../images/groups/icons/group_icon_small_owner.png');
+ background: url("../images/groups/icons/group_icon_small_owner.png");
width: 13px;
height: 13px;
}
&.icon-navigator-info {
- background: url('../images/navigator/icons/info.png');
+ background: url("../images/navigator/icons/info.png");
width: 18px;
height: 18px;
}
&.icon-navigator-room-locked {
- background: url('../images/navigator/icons/room_locked.png');
+ background: url("../images/navigator/icons/room_locked.png");
width: 13px;
height: 16px;
}
&.icon-navigator-room-password {
- background: url('../images/navigator/icons/room_password.png');
+ background: url("../images/navigator/icons/room_password.png");
width: 13px;
height: 16px;
}
&.icon-navigator-room-invisible {
- background: url('../images/navigator/icons/room_invisible.png');
+ background: url("../images/navigator/icons/room_invisible.png");
width: 13px;
height: 16px;
}
&.icon-navigator-room-group {
- background: url('../images/navigator/icons/room_group.png');
+ background: url("../images/navigator/icons/room_group.png");
width: 13px;
height: 11px;
}
&.icon-youtube-next {
- background: url('../images/room-widgets/youtube-widget/next.png');
+ background: url("../images/room-widgets/youtube-widget/next.png");
width: 21px;
height: 16px;
}
&.icon-youtube-prev {
- background: url('../images/room-widgets/youtube-widget/prev.png');
+ background: url("../images/room-widgets/youtube-widget/prev.png");
width: 21px;
height: 16px;
}
&.icon-hc-banner {
- background: url('../images/catalog/hc_big.png');
+ background: url("../images/catalog/hc_big.png");
width: 68px;
height: 40px;
}
&.icon-set-tile {
- background-image: url('../images/floorplaneditor/icon-tile-set.png');
+ background-image: url("../images/floorplaneditor/icon-tile-set.png");
width: 40px;
height: 40px;
}
&.icon-unset-tile {
- background-image: url('../images/floorplaneditor/icon-tile-unset.png');
+ background-image: url("../images/floorplaneditor/icon-tile-unset.png");
width: 40px;
height: 40px;
}
&.icon-increase-height {
- background-image: url('../images/floorplaneditor/icon-tile-up.png');
+ background-image: url("../images/floorplaneditor/icon-tile-up.png");
width: 40px;
height: 40px;
}
&.icon-decrease-height {
- background-image: url('../images/floorplaneditor/icon-tile-down.png');
+ background-image: url("../images/floorplaneditor/icon-tile-down.png");
width: 40px;
height: 40px;
}
&.icon-set-door {
- background-image: url('../images/floorplaneditor/icon-door.png');
+ background-image: url("../images/floorplaneditor/icon-door.png");
width: 40px;
height: 40px;
}
&.icon-door-direction-0 {
- background-image: url('../images/floorplaneditor/door-direction-0.png');
+ background-image: url("../images/floorplaneditor/door-direction-0.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-1 {
- background-image: url('../images/floorplaneditor/door-direction-1.png');
+ background-image: url("../images/floorplaneditor/door-direction-1.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-2 {
- background-image: url('../images/floorplaneditor/door-direction-2.png');
+ background-image: url("../images/floorplaneditor/door-direction-2.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-3 {
- background-image: url('../images/floorplaneditor/door-direction-3.png');
+ background-image: url("../images/floorplaneditor/door-direction-3.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-4 {
- background-image: url('../images/floorplaneditor/door-direction-4.png');
+ background-image: url("../images/floorplaneditor/door-direction-4.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-5 {
- background-image: url('../images/floorplaneditor/door-direction-5.png');
+ background-image: url("../images/floorplaneditor/door-direction-5.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-6 {
- background-image: url('../images/floorplaneditor/door-direction-6.png');
+ background-image: url("../images/floorplaneditor/door-direction-6.png");
width: 80px;
height: 45px;
}
&.icon-door-direction-7 {
- background-image: url('../images/floorplaneditor/door-direction-7.png');
+ background-image: url("../images/floorplaneditor/door-direction-7.png");
width: 80px;
height: 45px;
}
&.icon-tickets {
- background-image: url('../images/icons/tickets.png');
+ background-image: url("../images/icons/tickets.png");
width: 17px;
height: 17px;
}
&.icon-user {
- background-image: url('../images/icons/user.png');
+ background-image: url("../images/icons/user.png");
width: 18px;
height: 19px;
}
diff --git a/src/components/game-center/GameCenterView.scss b/src/components/game-center/GameCenterView.scss
new file mode 100644
index 00000000..7f8bd623
--- /dev/null
+++ b/src/components/game-center/GameCenterView.scss
@@ -0,0 +1,44 @@
+.game-center-stage {
+ width: 100%;
+ height: calc(100% - 55px);
+ background-color: black;
+ position: absolute;
+ inset: 0;
+}
+.game-center-main {
+ width: 1280px;
+ height: calc(100% - 55px);
+ background: #93d4f3;
+
+ .game-view {
+ background-position: bottom center;
+ background-repeat: no-repeat;
+
+ > div {
+ color: inherit;
+ }
+ }
+
+ .gameList-container {
+ min-height: 107px;
+
+ .game-icon {
+ width: 83px;
+ height: 83px;
+ background-position: center;
+ background-repeat: no-repeat;
+
+ &.selected {
+ position: relative;
+ &::after {
+ content: "";
+ background-image: url("../../assets/images/gamecenter/selectedIcon.png");
+ width: 83px;
+ height: 83px;
+ position: absolute;
+ inset: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/game-center/GameCenterView.tsx b/src/components/game-center/GameCenterView.tsx
new file mode 100644
index 00000000..f0955ae6
--- /dev/null
+++ b/src/components/game-center/GameCenterView.tsx
@@ -0,0 +1,50 @@
+import { ILinkEventTracker } from '@nitrots/nitro-renderer';
+import { useEffect } from 'react';
+import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api';
+import { Flex } from '../../common';
+import { useGameCenter } from '../../hooks';
+import { GameListView } from './views/GameListView';
+import { GameStageView } from './views/GameStageView';
+import { GameView } from './views/GameView';
+
+export const GameCenterView = () =>
+{
+ const{ isVisible, setIsVisible, games, accountStatus } = useGameCenter();
+
+ useEffect(() =>
+ {
+ const toggleGameCenter = () =>
+ {
+ setIsVisible(prev => !prev);
+ }
+
+ const linkTracker: ILinkEventTracker = {
+ linkReceived: (url: string) =>
+ {
+ const value = url.split('/');
+
+ switch(value[1])
+ {
+ case 'toggle':
+ toggleGameCenter();
+ break;
+ }
+ },
+ eventUrlPrefix: 'games/'
+ };
+
+ AddEventLinkTracker(linkTracker);
+
+ return () => RemoveLinkEventTracker(linkTracker);
+ }, [ ]);
+
+ if(!isVisible || !games || !accountStatus) return;
+
+ return
+
+
+
+
+
+
+}
diff --git a/src/components/game-center/views/GameListView.tsx b/src/components/game-center/views/GameListView.tsx
new file mode 100644
index 00000000..1211bc75
--- /dev/null
+++ b/src/components/game-center/views/GameListView.tsx
@@ -0,0 +1,32 @@
+import { GameConfigurationData } from '@nitrots/nitro-renderer';
+import { LocalizeText } from '../../../api';
+import { Base, Flex } from '../../../common';
+import { useGameCenter } from '../../../hooks';
+
+export const GameListView = () =>
+{
+ const { games,selectedGame, setSelectedGame } = useGameCenter();
+
+ const getClasses = (game: GameConfigurationData) =>
+ {
+ let classes = [ 'game-icon' ];
+
+ if(selectedGame === game) classes.push('selected');
+
+ return classes.join(' ');
+ }
+
+ const getIconImage = (game: GameConfigurationData): string =>
+ {
+ return `url(${ game.assetUrl }${ game.gameNameId }_icon.png)`
+ }
+
+ return
+ { LocalizeText('gamecenter.game_list_title') }
+
+ { games && games.map((game,index) =>
+ setSelectedGame(game) } style={ { backgroundImage: getIconImage(game) } }/>
+ ) }
+
+
+}
diff --git a/src/components/game-center/views/GameStageView.tsx b/src/components/game-center/views/GameStageView.tsx
new file mode 100644
index 00000000..0a26fea4
--- /dev/null
+++ b/src/components/game-center/views/GameStageView.tsx
@@ -0,0 +1,47 @@
+import { Game2ExitGameMessageComposer } from '@nitrots/nitro-renderer';
+import { useEffect, useRef, useState } from 'react';
+import { SendMessageComposer } from '../../../api';
+import { Base } from '../../../common';
+import { useGameCenter } from '../../../hooks';
+
+export const GameStageView = () =>
+{
+ const { gameURL,setGameURL } = useGameCenter();
+ const [ loadTimes, setLoadTimes ] = useState(0);
+ const ref = useRef();
+
+ useEffect(()=>
+ {
+ if(!ref || ref && !ref.current) return;
+
+ setLoadTimes(0);
+
+ let frame: HTMLIFrameElement = document.createElement('iframe');
+
+ frame.src = gameURL;
+ frame.classList.add('game-center-stage');
+ frame.classList.add('h-100');
+
+ frame.onload = () =>
+ {
+ setLoadTimes(prev => prev += 1)
+ }
+
+ ref.current.innerHTML = '';
+ ref.current.appendChild(frame);
+
+ },[ ref, gameURL ]);
+
+ useEffect(()=>
+ {
+ if(loadTimes > 1)
+ {
+ setGameURL(null);
+ SendMessageComposer(new Game2ExitGameMessageComposer());
+ }
+ },[ loadTimes,setGameURL ])
+
+ if(!gameURL) return null;
+
+ return
+}
diff --git a/src/components/game-center/views/GameView.tsx b/src/components/game-center/views/GameView.tsx
new file mode 100644
index 00000000..a9d641f7
--- /dev/null
+++ b/src/components/game-center/views/GameView.tsx
@@ -0,0 +1,58 @@
+import { Game2GetAccountGameStatusMessageComposer, GetGameStatusMessageComposer, JoinQueueMessageComposer } from '@nitrots/nitro-renderer';
+import { useEffect } from 'react';
+import { ColorUtils, LocalizeText, SendMessageComposer } from '../../../api';
+import { Base, Button, Flex, LayoutItemCountView, Text } from '../../../common';
+import { useGameCenter } from '../../../hooks';
+
+export const GameView = () =>
+{
+ const { selectedGame, accountStatus } = useGameCenter();
+
+ useEffect(()=>
+ {
+ if(selectedGame)
+ {
+ SendMessageComposer(new GetGameStatusMessageComposer(selectedGame.gameId));
+ SendMessageComposer(new Game2GetAccountGameStatusMessageComposer(selectedGame.gameId));
+ }
+ },[ selectedGame ])
+
+ const getBgColour = (): string =>
+ {
+ return ColorUtils.uintHexColor(selectedGame.bgColor)
+ }
+
+ const getBgImage = (): string =>
+ {
+ return `url(${ selectedGame.assetUrl }${ selectedGame.gameNameId }_theme.png)`
+ }
+
+ const getColor = () =>
+ {
+ return ColorUtils.uintHexColor(selectedGame.textColor);
+ }
+
+ const onPlay = () =>
+ {
+ SendMessageComposer(new JoinQueueMessageComposer(selectedGame.gameId));
+ }
+
+ return
+
+ { LocalizeText(`gamecenter.${ selectedGame.gameNameId }.description_title`) }
+
+ { (accountStatus.hasUnlimitedGames || accountStatus.freeGamesLeft > 0) && <>
+
+ > }
+ { LocalizeText(`gamecenter.${ selectedGame.gameNameId }.description_content`) }
+
+
+
+
+
+
+}
diff --git a/src/components/index.scss b/src/components/index.scss
index 5cea1b3b..5f4c0268 100644
--- a/src/components/index.scss
+++ b/src/components/index.scss
@@ -1,26 +1,27 @@
-@import './achievements/AchievementsView';
-@import './avatar-editor/AvatarEditorView';
-@import './camera/CameraWidgetView';
-@import './campaign/CampaignView';
-@import './catalog/CatalogView';
-@import './chat-history/ChatHistoryView';
-@import './floorplan-editor/FloorplanEditorView';
-@import './friends/FriendsView';
-@import './groups/GroupView';
-@import './guide-tool/GuideToolView';
-@import './hc-center/HcCenterView';
-@import './help/HelpView';
-@import './hotel-view/HotelView';
-@import './inventory/InventoryView';
-@import './loading/LoadingView';
-@import './mod-tools/ModToolsView';
-@import './navigator/NavigatorView';
-@import './nitropedia/NitropediaView';
-@import './notification-center/NotificationCenterView';
-@import './purse/PurseView';
-@import './right-side/RightSideView';
-@import './room/RoomView';
-@import './toolbar/ToolbarView';
-@import './user-profile/UserProfileVew';
-@import './user-settings/UserSettingsView';
-@import './wired/WiredView';
+@import "./achievements/AchievementsView";
+@import "./avatar-editor/AvatarEditorView";
+@import "./camera/CameraWidgetView";
+@import "./campaign/CampaignView";
+@import "./catalog/CatalogView";
+@import "./chat-history/ChatHistoryView";
+@import "./floorplan-editor/FloorplanEditorView";
+@import "./friends/FriendsView";
+@import "./groups/GroupView";
+@import "./guide-tool/GuideToolView";
+@import "./hc-center/HcCenterView";
+@import "./help/HelpView";
+@import "./hotel-view/HotelView";
+@import "./inventory/InventoryView";
+@import "./loading/LoadingView";
+@import "./mod-tools/ModToolsView";
+@import "./navigator/NavigatorView";
+@import "./nitropedia/NitropediaView";
+@import "./notification-center/NotificationCenterView";
+@import "./purse/PurseView";
+@import "./right-side/RightSideView";
+@import "./room/RoomView";
+@import "./toolbar/ToolbarView";
+@import "./user-profile/UserProfileVew";
+@import "./user-settings/UserSettingsView";
+@import "./wired/WiredView";
+@import "./game-center/GameCenterView.scss";
diff --git a/src/components/main/MainView.tsx b/src/components/main/MainView.tsx
index 3dec4d05..f54ad251 100644
--- a/src/components/main/MainView.tsx
+++ b/src/components/main/MainView.tsx
@@ -11,6 +11,7 @@ import { CatalogView } from '../catalog/CatalogView';
import { ChatHistoryView } from '../chat-history/ChatHistoryView';
import { FloorplanEditorView } from '../floorplan-editor/FloorplanEditorView';
import { FriendsView } from '../friends/FriendsView';
+import { GameCenterView } from '../game-center/GameCenterView';
import { GroupsView } from '../groups/GroupsView';
import { GuideToolView } from '../guide-tool/GuideToolView';
import { HcCenterView } from '../hc-center/HcCenterView';
@@ -105,6 +106,7 @@ export const MainView: FC<{}> = props =>
+
);
}
diff --git a/src/components/toolbar/ToolbarView.tsx b/src/components/toolbar/ToolbarView.tsx
index 5b7081bd..0efab76f 100644
--- a/src/components/toolbar/ToolbarView.tsx
+++ b/src/components/toolbar/ToolbarView.tsx
@@ -1,6 +1,6 @@
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, PerkAllowancesMessageEvent, PerkEnum, Queue, Wait } from '@nitrots/nitro-renderer';
import { FC, useState } from 'react';
-import { CreateLinkEvent, GetSessionDataManager, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api';
+import { CreateLinkEvent, GetConfiguration, GetSessionDataManager, MessengerIconState, OpenMessengerChat, VisitDesktop } from '../../api';
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
import { useAchievements, useFriends, useInventoryUnseenTracker, useMessageEvent, useMessenger, useRoomEngineEvent, useSessionInfo } from '../../hooks';
import { ToolbarMeView } from './ToolbarMeView';
@@ -81,6 +81,7 @@ export const ToolbarView: FC<{ isInRoom: boolean }> = props =>
{ !isInRoom &&
CreateLinkEvent('navigator/goto/home') } /> }
CreateLinkEvent('navigator/toggle') } />
+ { GetConfiguration('game.center.enabled') && CreateLinkEvent('games/toggle') } /> }
CreateLinkEvent('catalog/toggle') } />
CreateLinkEvent('inventory/toggle') }>
{ (getFullCount > 0) &&
diff --git a/src/hooks/game-center/index.ts b/src/hooks/game-center/index.ts
new file mode 100644
index 00000000..59f04720
--- /dev/null
+++ b/src/hooks/game-center/index.ts
@@ -0,0 +1 @@
+export * from './useGameCenter';
diff --git a/src/hooks/game-center/useGameCenter.ts b/src/hooks/game-center/useGameCenter.ts
new file mode 100644
index 00000000..0b9dbcb6
--- /dev/null
+++ b/src/hooks/game-center/useGameCenter.ts
@@ -0,0 +1,83 @@
+import { Game2AccountGameStatusMessageEvent, Game2AccountGameStatusMessageParser, GameConfigurationData, GameListMessageEvent, GameStatusMessageEvent, GetGameListMessageComposer, LoadGameUrlEvent } from '@nitrots/nitro-renderer';
+import { useEffect, useState } from 'react';
+import { useBetween } from 'use-between';
+import { SendMessageComposer, VisitDesktop } from '../../api';
+import { useMessageEvent } from '../events';
+
+const useGameCenterState = () =>
+{
+ const [ isVisible, setIsVisible ] = useState(false);
+ const [ games, setGames ] = useState(null);
+ const [ selectedGame, setSelectedGame ] = useState(null);
+ const [ accountStatus, setAccountStatus ] = useState(null);
+ const [ gameOffline, setGameOffline ] = useState(false);
+ const [ gameURL, setGameURL ] = useState(null);
+
+ useMessageEvent(GameListMessageEvent, event =>
+ {
+ let parser = event.getParser();
+
+ if(!parser || parser && !parser.games.length) return;
+
+ setSelectedGame(parser.games[0]);
+
+ setGames(parser.games);
+ });
+
+ useMessageEvent(Game2AccountGameStatusMessageEvent, event =>
+ {
+ let parser = event.getParser();
+
+ if(!parser) return;
+
+ setAccountStatus(parser);
+ });
+
+ useMessageEvent(GameStatusMessageEvent, event =>
+ {
+ let parser = event.getParser();
+
+ if(!parser) return;
+
+ setGameOffline(parser.isInMaintenance);
+ })
+
+ useMessageEvent(LoadGameUrlEvent, event =>
+ {
+ let parser = event.getParser();
+
+ if(!parser) return;
+
+ switch(parser.gameTypeId)
+ {
+ case 2:
+ return console.log('snowwar')
+ default:
+ return setGameURL(parser.url);
+ }
+ });
+
+ useEffect(()=>
+ {
+ if(isVisible)
+ {
+ SendMessageComposer(new GetGameListMessageComposer());
+ VisitDesktop();
+ }
+ else
+ {
+ // dispose or wtv
+ }
+ },[ isVisible ]);
+
+ return {
+ isVisible, setIsVisible,
+ games,
+ accountStatus,
+ selectedGame, setSelectedGame,
+ gameOffline,
+ gameURL, setGameURL
+ }
+}
+
+export const useGameCenter = () => useBetween(useGameCenterState);
diff --git a/src/hooks/index.ts b/src/hooks/index.ts
index 91a23d23..a5515749 100644
--- a/src/hooks/index.ts
+++ b/src/hooks/index.ts
@@ -6,6 +6,7 @@ export * from './events';
export * from './events/core';
export * from './events/nitro';
export * from './friends';
+export * from './game-center';
export * from './groups';
export * from './help';
export * from './inventory';