Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes for better script online compatibility #369

Merged
merged 20 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0c65be3
WIP rollback function hook
estebanfer Feb 2, 2024
5a590a5
add local_data to StateMemory, to allow script data that gets affecte…
estebanfer Feb 9, 2024
2543422
hook rollback function with patch_and_redirect and fix it
estebanfer Feb 11, 2024
9a994e4
Merge branch 'main' into online-compat-stuff
estebanfer Feb 12, 2024
bbffae5
Merge branch 'main' into online-compat-stuff
estebanfer Mar 6, 2024
a91419c
Move local_state_datas to LocalStateData struct
estebanfer Mar 6, 2024
f2e4f8b
Merge branch 'main' into online-compat-stuff
estebanfer Mar 7, 2024
e70fa55
make more callbacks online compatible, fix deadlock
estebanfer Mar 8, 2024
79c13f3
format
estebanfer Mar 8, 2024
43386cb
docs, rename clone_heap -> copy_state, state local_data -> user_data
estebanfer Mar 29, 2024
8df6529
change state location to read-only via getter
estebanfer Mar 31, 2024
488d643
trigger PRE_COPY_STATE on Overlunky savestates
estebanfer Apr 10, 2024
c704236
move State::get_location to header file
estebanfer Apr 10, 2024
3881f06
minor autodoc fix
estebanfer Apr 11, 2024
7e9c411
remove PRE_COPY_STATE lua event for now
estebanfer May 1, 2024
f105e88
fix get_local_* return type in docs
estebanfer May 3, 2024
f93ee54
fix spawn_api and custom_allocator online
estebanfer Jun 3, 2024
4b1a8b2
Merge branch 'main' into online-compat-stuff
estebanfer Aug 3, 2024
98cb792
better deepcopy_object implementation
estebanfer Aug 3, 2024
9f70235
change get_location to get_offset, remove get_state_offset
estebanfer Aug 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/game_data/spel2.lua

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

6 changes: 3 additions & 3 deletions docs/src/includes/_globals.md
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ Gets a grid entity, such as floor or spikes, at the given position and layer.

> Search script examples for [get_local_players](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_local_players)

#### nil get_local_players()
#### vector<[Player](#Player)> get_local_players()

Get the thread-local version of players

Expand Down Expand Up @@ -1542,7 +1542,7 @@ Get the current layer that the liquid is spawn in. Related function [set_liquid_

> Search script examples for [get_local_prng](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_local_prng)

#### nil get_local_prng()
#### [PRNG](#PRNG) get_local_prng()

Get the thread-local version of prng

Expand All @@ -1551,7 +1551,7 @@ Get the thread-local version of prng

> Search script examples for [get_local_state](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=get_local_state)

#### nil get_local_state()
#### [StateMemory](#StateMemory) get_local_state()

Get the thread-local version of state

Expand Down
1 change: 1 addition & 0 deletions docs/src/includes/_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -3115,6 +3115,7 @@ array<[THEME](#THEME), 9> | [journal_progress_theme_slots](https://github.
[LiquidPhysics](#LiquidPhysics) | [liquid](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=liquid) |
int | [next_entity_uid](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=next_entity_uid) | Next entity spawned will have this uid
[RoomOwnersInfo](#RoomOwnersInfo) | [room_owners](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=room_owners) | Holds info about owned rooms and items (shops, challenge rooms, vault etc.)
any | [user_data](https://github.com/spelunky-fyi/overlunky/search?l=Lua&q=user_data) | You can store a table (or lua primitive) here and it will store data correctly in online multiplayer, by having a different copy on each state and being copied over when the game does.<br/>Doesn't support recursive tables / cyclic references. Metatables will be transferred by reference instead of being copied<br/>

## Texture types

Expand Down
6 changes: 4 additions & 2 deletions src/game_api/containers/custom_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ using CustomFreeFun = void*(void*, void*);
void* custom_malloc(std::size_t size)
{
static CustomMallocFun* _malloc = (CustomMallocFun*)get_address("custom_malloc"sv);
static void* _alloc_base = OnHeapPointer<void>(*(size_t*)get_address("malloc_base"sv)).decode(); // probably should be decode_local
static size_t _heap_ptr_malloc_base = *reinterpret_cast<size_t*>(get_address("malloc_base"sv));
void* _alloc_base = OnHeapPointer<void>(_heap_ptr_malloc_base).decode_local();
return _malloc(_alloc_base, size);
}
void custom_free(void* mem)
{
static CustomFreeFun* _free = (CustomFreeFun*)get_address("custom_free"sv);
static void* _alloc_base = OnHeapPointer<void>(*(size_t*)get_address("malloc_base"sv)).decode(); // probably should be decode_local
static size_t _heap_ptr_malloc_base = *reinterpret_cast<size_t*>(get_address("malloc_base"sv));
void* _alloc_base = OnHeapPointer<void>(_heap_ptr_malloc_base).decode_local();
_free(_alloc_base, mem);
}
29 changes: 16 additions & 13 deletions src/game_api/savestate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@
#include "script/events.hpp" // for pre_load_state
#include "state.hpp" // for State, get_state_ptr, enum_to_layer

size_t get_state_offset()
StateMemory* get_save_state_raw(int slot)
{
auto addr = get_address("state_location");
if (addr)
return memory_read<size_t>(addr);
return 0x4a0;
size_t arr = get_address("save_states");
size_t base = memory_read<size_t>(arr + (slot - 1) * 8);
auto state = reinterpret_cast<StateMemory*>(base + State::get().get_offset());
return state;
}

void copy_save_slot(int from, int to)
{
if ((from == 5 && pre_save_state(to, get_save_state(to))) ||
(to == 5 && pre_load_state(from, get_save_state(from))))
return;
pre_copy_state_event(get_save_state_raw(from), get_save_state_raw(to));
size_t arr = get_address("save_states");
size_t fromBaseState = memory_read<size_t>(arr + (from - 1) * 8);
size_t toBaseState = memory_read<size_t>(arr + (to - 1) * 8);
Expand Down Expand Up @@ -57,9 +58,7 @@ void copy_state(size_t fromBaseState, size_t toBaseState)

StateMemory* get_save_state(int slot)
{
size_t arr = get_address("save_states");
size_t base = memory_read<size_t>(arr + (slot - 1) * 8);
auto state = reinterpret_cast<StateMemory*>(base + get_state_offset());
auto state = get_save_state_raw(slot);
if (state->screen)
return state;
return nullptr;
Expand Down Expand Up @@ -88,15 +87,17 @@ StateMemory* SaveState::get_state() const
{
if (!addr)
return nullptr;
return reinterpret_cast<StateMemory*>(addr + get_state_offset());
return reinterpret_cast<StateMemory*>(addr + State::get().get_offset());
}

void SaveState::load()
{
if (!addr)
return;
size_t to = (size_t)(State::get().ptr_main()) - get_state_offset();
auto state = reinterpret_cast<StateMemory*>(addr + get_state_offset());
State& state_g = State::get();
size_t offset = state_g.get_offset();
size_t to = (size_t)(state_g.ptr_main()) - offset;
auto state = reinterpret_cast<StateMemory*>(addr + offset);
if (pre_load_state(-1, state))
return;
copy_state(addr, to);
Expand All @@ -107,8 +108,10 @@ void SaveState::save()
{
if (!addr)
return;
size_t from = (size_t)(State::get().ptr_main()) - get_state_offset();
auto state = reinterpret_cast<StateMemory*>(addr + get_state_offset());
State& state_g = State::get();
size_t offset = state_g.get_offset();
size_t from = (size_t)(state_g.ptr_main()) - offset;
auto state = reinterpret_cast<StateMemory*>(addr + offset);
if (pre_save_state(-1, state))
return;
copy_state(from, addr);
Expand Down
10 changes: 10 additions & 0 deletions src/game_api/script/events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,13 @@ void post_event(ON event)
return true;
});
}

void pre_copy_state_event(StateMemory* from, StateMemory* to)
{
LuaBackend::for_each_backend(
[&](LuaBackend::LockedBackend backend)
{
backend->pre_copy_state(from, to);
return true;
});
}
1 change: 1 addition & 0 deletions src/game_api/script/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ bool pre_unload_level();
bool pre_unload_layer(LAYER layer);
bool pre_save_state(int slot, StateMemory* saved);
bool pre_load_state(int slot, StateMemory* loaded);
void pre_copy_state_event(StateMemory* from, StateMemory* to);

void post_load_screen();
void post_init_layer(LAYER layer);
Expand Down
Loading
Loading