Skip to content

Commit

Permalink
implement online lobby stuff (#148)
Browse files Browse the repository at this point in the history
  • Loading branch information
zappatic authored Sep 20, 2021
1 parent 37a356d commit d00a6b1
Show file tree
Hide file tree
Showing 13 changed files with 915 additions and 404 deletions.
13 changes: 13 additions & 0 deletions docs/game_data/spel2.lua

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion docs/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"../src/game_api/items.hpp",
"../src/game_api/screen.hpp",
"../src/game_api/screen_arena.hpp",
"../src/game_api/online.hpp",
"../src/game_api/script/usertypes/level_lua.hpp",
"../src/game_api/script/usertypes/gui_lua.hpp",
"../src/game_api/script/usertypes/vanilla_render_lua.hpp",
Expand Down Expand Up @@ -73,6 +74,7 @@
"../src/game_api/script/usertypes/char_state_lua.cpp",
"../src/game_api/script/usertypes/hitbox_lua.cpp",
"../src/game_api/script/usertypes/screen_lua.cpp",
"../src/game_api/script/usertypes/screen_arena_lua.cpp",
]
rpc = []
classes = []
Expand Down Expand Up @@ -107,7 +109,7 @@
"variadic_args va": "int, int...",
}
comment = []
not_functions = ["players", "state", "savegame", "options", "meta", "prng"]
not_functions = ["players", "state", "game_manager", "online", "savegame", "options", "meta", "prng"]
skip = False


Expand Down
136 changes: 104 additions & 32 deletions docs/script-api.md

Large diffs are not rendered by default.

20 changes: 19 additions & 1 deletion src/game_api/game_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@ struct TmpStruct
OnHeapPointer<SaveData> savedata;
};

struct GameProps
{
uint32_t buttons;
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t buttons_dupe;
uint32_t unknown4;
uint32_t unknown5;
uint32_t unknown6;
uint32_t buttons_dupe_but_different;
int8_t unknown8;
bool game_has_focus;
bool unknown9;
bool unknown10;
// there's more stuff here
};

struct GameManager
{
void* backgroundmusic;
TmpStruct* tmp;
uint8_t buttons_controls[MAX_PLAYERS];
uint8_t buttons_movement[MAX_PLAYERS];
size_t more_button_states;
GameProps* game_props;

// screen pointers below are most likely in an array and indexed through the screen ID, hence the nullptrs for
// screens that are available in State
Expand Down
19 changes: 19 additions & 0 deletions src/game_api/online.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "online.hpp"
#include "memory.hpp"
#include "search.hpp"

Online* get_online()
{
ONCE(Online*)
{
auto mem = Memory::get();
auto tmp = find_inst(mem.exe(), "\xF3\x0F\x11\x4C\x24\x10\x56\x57"s, mem.after_bundle);
tmp = mem.at_exe(decode_pc(mem.exe(), tmp + 24));
return res = *(Online**)tmp;
}
}

std::string OnlineLobby::get_code()
{
return fmt::format("{:X}", code);
}
79 changes: 79 additions & 0 deletions src/game_api/online.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <array>
#include <cstdint>

struct OnlinePlayer
{
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t unknown4;
uint8_t unknown5;
uint8_t ready_state;
uint8_t character;
char player_name[37];
};

struct OnlineLobby
{
uint32_t code;
uint32_t unknown1;
uint32_t keys_pressed;
uint32_t keys_pressed_sync;
uint8_t unknown2;
uint8_t unknown3;
int8_t unknown4;
int8_t unknown5;
uint32_t unknown6;
int8_t unknown7;
int8_t unknown8;
uint8_t unknown9;
uint8_t unknown10;
int32_t unknown11;
int32_t unknown12;
int8_t unknown13;
int8_t unknown14;
uint8_t unknown15;
uint8_t unknown16;
uint32_t unknown17;
uint8_t unknown18;
uint8_t unknown19;
int8_t unknown20;
int8_t unknown21;
int8_t unknown22;
uint8_t unknown23;
uint8_t unknown24;
uint8_t unknown25;
uint32_t unknown26;

/// Gets the string equivalent of the code
std::string get_code();
};

class Online
{
public:
uint32_t unknown1;
uint32_t unknown2;
uint64_t unknown3;
uint64_t unknown4;
uint64_t unknown5;
uint32_t unknown6;
uint32_t unknown7;
uint32_t unknown8;
uint32_t unknown9;
uint32_t unknown10;
uint32_t unknown11;
uint32_t unknown12;
uint32_t unknown13;
std::array<OnlinePlayer, 4> online_players;
OnlinePlayer local_player;
OnlineLobby lobby;
OnlineLobby lobby_dupe;
// some more stuff

virtual ~Online() = 0;
};

Online* get_online();
25 changes: 25 additions & 0 deletions src/game_api/screen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,28 @@ void Screen::unhook(std::uint32_t id)
{ return hook.id == id; });
}
}

void ScreenOnlineLobby::set_code(const std::string& code)
{
if (code.length() != 8)
{
characters_entered_count = 0;
return;
}
std::string code_upper = code;
std::transform(code_upper.begin(), code_upper.end(), code_upper.begin(), [](unsigned char c)
{ return (unsigned char)std::toupper(c); });

for (size_t x = 0; x < 8; ++x)
{
const unsigned char c = code.at(x);
auto valid = (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
if (!valid)
{
characters_entered_count = 0;
return;
}
code_chars[x] = c;
}
characters_entered_count = 8;
}
121 changes: 120 additions & 1 deletion src/game_api/screen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,9 +658,128 @@ class ScreenOnlineLoading : public Screen // ID: 28
float ouroboros_angle;
};

struct OnlineLobbyScreenPlayer
{
uint8_t unknown1;
uint8_t character;
bool ready;
uint8_t unknown2;
};

class ScreenOnlineLobby : public Screen // ID: 29
{
public: // not reverse engineered
public:
uint8_t unknown2;
uint8_t unknown3;
uint8_t unknown4;
uint8_t unknown5;
float woodpanels_slidein_timer;
float scroll_unfurl_timer;
uint32_t unknown8;
uint32_t unknown9;
TextureRenderingInfo woodpanel_bottom;
TextureRenderingInfo woodpanel_top;
TextureRenderingInfo unknown13;
TextureRenderingInfo left_scroll_handle;
TextureRenderingInfo right_scroll_handle;
uint32_t scroll_text_id;
uint32_t btn_left_text_id;
uint32_t btn_right_text_id;
uint32_t btn_center_text_id;
bool woodpanel_top_visible;
bool woodpanel_bottom_visible;
bool toggle_panels_slidein;
bool unknown21;
std::array<OnlineLobbyScreenPlayer, 4> players;
TextureRenderingInfo background_image;
size_t unknown22;
size_t unknown23;
size_t unknown24;
size_t unknown25;
size_t unknown26;
size_t unknown27;
size_t unknown28;
size_t unknown29;
size_t unknown30;
TextureRenderingInfo unknown36;
TextureRenderingInfo unknown37;
float unknown38;
TextureRenderingInfo topleft_woodpanel_esc;
float topleft_woodpanel_esc_slidein_timer;
float character_walk_offset;
bool character_facing_left;
int8_t move_direction;
uint8_t unknown41;
uint8_t unknown42;
TextureRenderingInfo character;
TextureRenderingInfo player_ready_icon;
float render_timer_dupe;
TextureRenderingInfo arrow_left;
TextureRenderingInfo arrow_right;
float another_timer;
float arrow_left_hor_offset;
float arrow_right_hor_offset;
TextureRenderingInfo platform_icon;
uint8_t player_count;
bool searching_for_players;
uint8_t unknown47;
uint8_t unknown48;
float another_timer_2;
bool show_code_panel;
uint8_t unknown49;
uint8_t unknown50;
uint8_t unknown51;
uint32_t unknown53;

// The following is actually class ScreenEnterOnlineCode but it has no direct pointer in GameManager
// or State. In assembly this pointer is accessed by &ScreenOnlineLobby + sizeof(ScreenOnlineLobby)
size_t enter_code_screen_vftable;
float enter_code_render_timer;
uint32_t unknown54;
float unknown56;
float enter_code_woodpanel_bottom_slidein_pos;
float unknown58;
float unknown59;
float unknown60;
TextureRenderingInfo enter_code_woodpanel_bottom;
TextureRenderingInfo unknown61;
TextureRenderingInfo unknown62;
TextureRenderingInfo unknown63;
TextureRenderingInfo unknown64;
uint32_t text_id_1;
uint32_t text_id_2;
uint32_t enter_code_btn_right_text_id;
uint32_t text_id_4;
bool enter_code_woodpanel_top_visible;
bool enter_code_woodpanel_bottom_visible;
bool enter_code_toggle_panels_slidein;
bool unknown68;
uint32_t unknown69;
uint32_t selected_character;
bool unknown71a;
uint8_t unknown71b;
uint16_t code_chars[8];
uint16_t code_char_terminator;
uint32_t characters_entered_count;
float enter_code_topleft_woodpanel_esc_slidein_timer;
uint32_t enter_code_banner_text_id;
uint32_t enter_code_OK_text_id;
TextureRenderingInfo enter_code_main_woodpanel_left;
TextureRenderingInfo enter_code_main_woodpanel_center;
TextureRenderingInfo enter_code_main_woodpanel_right;
TextureRenderingInfo enter_code_banner;
TextureRenderingInfo enter_code_char_cutouts;
TextureRenderingInfo enter_code_pointing_hand;
TextureRenderingInfo enter_code_buttons;
TextureRenderingInfo unknown85;
TextureRenderingInfo enter_code_OK_panel;
float enter_code_OK_panel_slidein_timer;
int32_t unknown87;
TextureRenderingInfo enter_code_your_code_scroll;
TextureRenderingInfo enter_code_your_code_scroll_left_handle;
TextureRenderingInfo enter_code_your_code_scroll_right_handle;

void set_code(const std::string& code);
};

struct PauseUI
Expand Down
5 changes: 5 additions & 0 deletions src/game_api/script/lua_vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "entities_items.hpp"
#include "entity.hpp"
#include "game_manager.hpp"
#include "online.hpp"
#include "rpc.hpp"
#include "spawn_api.hpp"
#include "state.hpp"
Expand Down Expand Up @@ -34,6 +35,7 @@
#include "usertypes/player_lua.hpp"
#include "usertypes/prng_lua.hpp"
#include "usertypes/save_context.hpp"
#include "usertypes/screen_arena_lua.hpp"
#include "usertypes/screen_lua.hpp"
#include "usertypes/sound_lua.hpp"
#include "usertypes/state_lua.hpp"
Expand Down Expand Up @@ -112,6 +114,7 @@ end
NState::register_usertypes(lua);
NPRNG::register_usertypes(lua);
NScreen::register_usertypes(lua);
NScreenArena::register_usertypes(lua);
NPlayer::register_usertypes(lua);
NDrops::register_usertypes(lua);
NCharacterState::register_usertypes(lua);
Expand All @@ -128,6 +131,8 @@ end
lua["state"] = get_state_ptr();
/// The GameManager gives access to a couple of Screens as well as the pause and journal UI elements
lua["game_manager"] = get_game_manager();
/// The Online object has information about the online lobby and its players
lua["online"] = get_online();
/// An array of [Player](#player) of the current players. Pro tip: You need `players[1].uid` in most entity functions.
lua["players"] = std::vector<Player*>(get_players());
/// Provides a read-only access to the save data, updated as soon as something changes (i.e. before it's written to savegame.sav.)
Expand Down
Loading

0 comments on commit d00a6b1

Please sign in to comment.