mirror of
https://codeberg.org/Nixietab/EOSSDK-Holos.git
synced 2026-08-21 20:23:28 -04:00
Initial commit.
This commit is contained in:
parent
3f8a1206d1
commit
0c1615c037
5 changed files with 2396 additions and 1 deletions
24
README.md
24
README.md
|
|
@ -1,3 +1,25 @@
|
||||||
|
### This project is being worked on and not everything works yet, contact me for help
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# EOSSDK-Holos
|
# EOSSDK-Holos
|
||||||
|
|
||||||
A emulation layer of EOSSDK that does it's best to enable true p2p multiplayer
|
EOSSDK-Holos is an emulation layer for the Epic Online Services (EOS) SDK. Its primary objective is to make possible true Peer-to-Peer multiplayer connectivity by intercepting and redirecting P2P traffic over a direct UDP socket.
|
||||||
|
|
||||||
|
|
||||||
|
# Build
|
||||||
|
|
||||||
|
1. Place the contents of this repository into the game's plugin directory:
|
||||||
|
|
||||||
|
`Holo's Hanafuda\HolosHanafuda_Data\Plugins\x86_64\`
|
||||||
|
|
||||||
|
|
||||||
|
The project acts as a DLL proxy. To ensure the game can still access the original SDK functions, you must rename the existing file:
|
||||||
|
|
||||||
|
|
||||||
|
2. Locate `EOSSDK-Win64-Shipping.dll` in the directory mentioned above and rename it to `EOSSDK-Win64-Shipping_orig.dll`.
|
||||||
|
|
||||||
|
|
||||||
|
Execute the build script provided in the repository to generate the proxy DLL:
|
||||||
|
|
||||||
|
```bash ./build.sh```
|
||||||
4
build.sh
Executable file
4
build.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
||||||
|
python3 gen_def.py
|
||||||
|
python3 gen_stubs.py
|
||||||
|
|
||||||
|
x86_64-w64-mingw32-g++ -shared -o EOSSDK-Win64-Shipping.dll main.cpp proxy_asm.s proxy.def -lws2_32 -static
|
||||||
136
gen_def.py
Normal file
136
gen_def.py
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open('dump.txt', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Find the [Ordinal/Name Pointer] Table
|
||||||
|
match = re.search(r'\[Ordinal/Name Pointer\] Table.*?\n(.*?)(\n\n|\Z)', content, re.DOTALL)
|
||||||
|
if not match:
|
||||||
|
print("Could not find Name Pointer Table in dump.txt")
|
||||||
|
return
|
||||||
|
|
||||||
|
lines = match.group(1).split('\n')
|
||||||
|
|
||||||
|
hooks = [
|
||||||
|
"EOS_P2P_SendPacket",
|
||||||
|
"EOS_P2P_GetNextReceivedPacketSize",
|
||||||
|
"EOS_P2P_ReceivePacket",
|
||||||
|
"EOS_P2P_AcceptConnection",
|
||||||
|
"EOS_P2P_CloseConnection",
|
||||||
|
"EOS_P2P_CloseConnections",
|
||||||
|
"EOS_P2P_QueryNATType",
|
||||||
|
"EOS_P2P_GetNATType",
|
||||||
|
"EOS_P2P_SetRelayControl",
|
||||||
|
"EOS_P2P_GetRelayControl",
|
||||||
|
"EOS_P2P_SetPortRange",
|
||||||
|
"EOS_P2P_GetPortRange",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionRequest",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionRequest",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionClosed",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionClosed",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionEstablished",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionEstablished",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionInterrupted",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionInterrupted",
|
||||||
|
"EOS_P2P_AddNotifyIncomingPacketQueueFull",
|
||||||
|
"EOS_P2P_RemoveNotifyIncomingPacketQueueFull",
|
||||||
|
"EOS_P2P_ClearPacketQueue",
|
||||||
|
"EOS_P2P_GetPacketQueueInfo",
|
||||||
|
"EOS_P2P_SetPacketQueueSize",
|
||||||
|
"EOS_Auth_Login",
|
||||||
|
"EOS_Connect_Login",
|
||||||
|
"EOS_Connect_CreateUser",
|
||||||
|
"EOS_EpicAccountId_FromString",
|
||||||
|
"EOS_ProductUserId_FromString",
|
||||||
|
"EOS_EpicAccountId_IsValid",
|
||||||
|
"EOS_ProductUserId_IsValid",
|
||||||
|
"EOS_ProductUserId_ToString",
|
||||||
|
"EOS_Connect_AddNotifyAuthExpiration",
|
||||||
|
"EOS_Lobby_CreateLobby",
|
||||||
|
"EOS_Lobby_JoinLobby",
|
||||||
|
"EOS_Lobby_CreateLobbySearch",
|
||||||
|
"EOS_LobbySearch_Find",
|
||||||
|
"EOS_LobbySearch_GetSearchResultCount",
|
||||||
|
"EOS_LobbySearch_CopySearchResultByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyInfo",
|
||||||
|
"EOS_LobbyDetails_GetLobbyOwner",
|
||||||
|
"EOS_LobbyDetails_Release",
|
||||||
|
"EOS_LobbySearch_Release",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyUpdateReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyUpdateReceived",
|
||||||
|
"EOS_LobbySearch_RemoveParameter",
|
||||||
|
"EOS_LobbySearch_SetLobbyId",
|
||||||
|
"EOS_LobbySearch_SetMaxResults",
|
||||||
|
"EOS_LobbySearch_SetParameter",
|
||||||
|
"EOS_LobbySearch_SetTargetUserId",
|
||||||
|
"EOS_LobbyModification_AddAttribute",
|
||||||
|
"EOS_LobbyModification_AddMemberAttribute",
|
||||||
|
"EOS_LobbyModification_Release",
|
||||||
|
"EOS_LobbyModification_RemoveAttribute",
|
||||||
|
"EOS_LobbyModification_RemoveMemberAttribute",
|
||||||
|
"EOS_LobbyModification_SetAllowedPlatformIds",
|
||||||
|
"EOS_LobbyModification_SetBucketId",
|
||||||
|
"EOS_LobbyModification_SetInvitesAllowed",
|
||||||
|
"EOS_LobbyModification_SetMaxMembers",
|
||||||
|
"EOS_LobbyModification_SetPermissionLevel",
|
||||||
|
"EOS_Lobby_UpdateLobbyModification",
|
||||||
|
"EOS_LobbyDetails_CopyAttributeByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyAttributeByKey",
|
||||||
|
"EOS_LobbyDetails_CopyMemberAttributeByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyMemberAttributeByKey",
|
||||||
|
"EOS_LobbyDetails_CopyMemberInfo",
|
||||||
|
"EOS_LobbyDetails_GetAttributeCount",
|
||||||
|
"EOS_LobbyDetails_GetMemberAttributeCount",
|
||||||
|
"EOS_LobbyDetails_GetMemberByIndex",
|
||||||
|
"EOS_LobbyDetails_GetMemberCount",
|
||||||
|
"EOS_LobbyDetails_Info_Release",
|
||||||
|
"EOS_LobbyDetails_MemberInfo_Release",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandle",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandleByInviteId",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandleByUiEventId",
|
||||||
|
"EOS_Lobby_UpdateLobby",
|
||||||
|
"EOS_Lobby_DestroyLobby",
|
||||||
|
"EOS_Lobby_LeaveLobby",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyMemberStatusReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyMemberStatusReceived",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyMemberUpdateReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyMemberUpdateReceived",
|
||||||
|
"EOS_Lobby_IsRTCRoomConnected",
|
||||||
|
"EOS_Lobby_GetRTCRoomName",
|
||||||
|
"EOS_Lobby_Attribute_Release",
|
||||||
|
"EOS_Connect_CopyIdToken",
|
||||||
|
"EOS_Connect_IdToken_Release",
|
||||||
|
"EOS_Connect_VerifyIdToken",
|
||||||
|
"EOS_Platform_Tick",
|
||||||
|
"EOS_Lobby_IsLobbyOwner",
|
||||||
|
"EOS_Lobby_GetInviteCount",
|
||||||
|
"EOS_Lobby_CopyInviteIdByIndex",
|
||||||
|
"EOS_Lobby_GetConnectString",
|
||||||
|
"EOS_Lobby_ParseConnectString",
|
||||||
|
"EOS_Platform_GetActiveCountryCode",
|
||||||
|
"EOS_Platform_GetActiveLocaleCode",
|
||||||
|
]
|
||||||
|
|
||||||
|
with open('proxy.def', 'w') as out:
|
||||||
|
out.write('LIBRARY "EOSSDK-Win64-Shipping.dll"\n')
|
||||||
|
out.write('EXPORTS\n')
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line: continue
|
||||||
|
# Parse line: [ 0] +base[ 1] 0000 EOS_Achievements_AddNotifyAchievementsUnlocked
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) >= 4:
|
||||||
|
func_name = parts[-1]
|
||||||
|
if func_name in hooks:
|
||||||
|
# Export our hook directly
|
||||||
|
out.write(f' {func_name}\n')
|
||||||
|
else:
|
||||||
|
# Forward to the original dll
|
||||||
|
out.write(f' {func_name}=EOSSDK-Win64-Shipping_orig.{func_name}\n')
|
||||||
|
|
||||||
|
print("proxy.def generated successfully.")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
149
gen_stubs.py
Normal file
149
gen_stubs.py
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open('dump.txt', 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
match = re.search(r'\[Ordinal/Name Pointer\] Table.*?\n(.*?)(\n\n|\Z)', content, re.DOTALL)
|
||||||
|
if not match:
|
||||||
|
print("Could not find Name Pointer Table in dump.txt")
|
||||||
|
return
|
||||||
|
|
||||||
|
lines = match.group(1).split('\n')
|
||||||
|
|
||||||
|
hooks = [
|
||||||
|
"EOS_P2P_SendPacket",
|
||||||
|
"EOS_P2P_GetNextReceivedPacketSize",
|
||||||
|
"EOS_P2P_ReceivePacket",
|
||||||
|
"EOS_P2P_AcceptConnection",
|
||||||
|
"EOS_P2P_CloseConnection",
|
||||||
|
"EOS_P2P_CloseConnections",
|
||||||
|
"EOS_P2P_QueryNATType",
|
||||||
|
"EOS_P2P_GetNATType",
|
||||||
|
"EOS_P2P_SetRelayControl",
|
||||||
|
"EOS_P2P_GetRelayControl",
|
||||||
|
"EOS_P2P_SetPortRange",
|
||||||
|
"EOS_P2P_GetPortRange",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionRequest",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionRequest",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionClosed",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionClosed",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionEstablished",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionEstablished",
|
||||||
|
"EOS_P2P_AddNotifyPeerConnectionInterrupted",
|
||||||
|
"EOS_P2P_RemoveNotifyPeerConnectionInterrupted",
|
||||||
|
"EOS_P2P_AddNotifyIncomingPacketQueueFull",
|
||||||
|
"EOS_P2P_RemoveNotifyIncomingPacketQueueFull",
|
||||||
|
"EOS_P2P_ClearPacketQueue",
|
||||||
|
"EOS_P2P_GetPacketQueueInfo",
|
||||||
|
"EOS_P2P_SetPacketQueueSize",
|
||||||
|
"EOS_Auth_Login",
|
||||||
|
"EOS_Connect_Login",
|
||||||
|
"EOS_Connect_CreateUser",
|
||||||
|
"EOS_EpicAccountId_FromString",
|
||||||
|
"EOS_ProductUserId_FromString",
|
||||||
|
"EOS_EpicAccountId_IsValid",
|
||||||
|
"EOS_ProductUserId_IsValid",
|
||||||
|
"EOS_ProductUserId_ToString",
|
||||||
|
"EOS_Connect_AddNotifyAuthExpiration",
|
||||||
|
"EOS_Lobby_CreateLobby",
|
||||||
|
"EOS_Lobby_JoinLobby",
|
||||||
|
"EOS_Lobby_CreateLobbySearch",
|
||||||
|
"EOS_LobbySearch_Find",
|
||||||
|
"EOS_LobbySearch_GetSearchResultCount",
|
||||||
|
"EOS_LobbySearch_CopySearchResultByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyInfo",
|
||||||
|
"EOS_LobbyDetails_GetLobbyOwner",
|
||||||
|
"EOS_LobbyDetails_Release",
|
||||||
|
"EOS_LobbySearch_Release",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyUpdateReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyUpdateReceived",
|
||||||
|
"EOS_LobbySearch_RemoveParameter",
|
||||||
|
"EOS_LobbySearch_SetLobbyId",
|
||||||
|
"EOS_LobbySearch_SetMaxResults",
|
||||||
|
"EOS_LobbySearch_SetParameter",
|
||||||
|
"EOS_LobbySearch_SetTargetUserId",
|
||||||
|
"EOS_LobbyModification_AddAttribute",
|
||||||
|
"EOS_LobbyModification_AddMemberAttribute",
|
||||||
|
"EOS_LobbyModification_Release",
|
||||||
|
"EOS_LobbyModification_RemoveAttribute",
|
||||||
|
"EOS_LobbyModification_RemoveMemberAttribute",
|
||||||
|
"EOS_LobbyModification_SetAllowedPlatformIds",
|
||||||
|
"EOS_LobbyModification_SetBucketId",
|
||||||
|
"EOS_LobbyModification_SetInvitesAllowed",
|
||||||
|
"EOS_LobbyModification_SetMaxMembers",
|
||||||
|
"EOS_LobbyModification_SetPermissionLevel",
|
||||||
|
"EOS_Lobby_UpdateLobbyModification",
|
||||||
|
"EOS_LobbyDetails_CopyAttributeByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyAttributeByKey",
|
||||||
|
"EOS_LobbyDetails_CopyMemberAttributeByIndex",
|
||||||
|
"EOS_LobbyDetails_CopyMemberAttributeByKey",
|
||||||
|
"EOS_LobbyDetails_CopyMemberInfo",
|
||||||
|
"EOS_LobbyDetails_GetAttributeCount",
|
||||||
|
"EOS_LobbyDetails_GetMemberAttributeCount",
|
||||||
|
"EOS_LobbyDetails_GetMemberByIndex",
|
||||||
|
"EOS_LobbyDetails_GetMemberCount",
|
||||||
|
"EOS_LobbyDetails_Info_Release",
|
||||||
|
"EOS_LobbyDetails_MemberInfo_Release",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandle",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandleByInviteId",
|
||||||
|
"EOS_Lobby_CopyLobbyDetailsHandleByUiEventId",
|
||||||
|
"EOS_Lobby_UpdateLobby",
|
||||||
|
"EOS_Lobby_DestroyLobby",
|
||||||
|
"EOS_Lobby_LeaveLobby",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyMemberStatusReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyMemberStatusReceived",
|
||||||
|
"EOS_Lobby_AddNotifyLobbyMemberUpdateReceived",
|
||||||
|
"EOS_Lobby_RemoveNotifyLobbyMemberUpdateReceived",
|
||||||
|
"EOS_Lobby_IsRTCRoomConnected",
|
||||||
|
"EOS_Lobby_GetRTCRoomName",
|
||||||
|
"EOS_Lobby_Attribute_Release",
|
||||||
|
"EOS_Connect_CopyIdToken",
|
||||||
|
"EOS_Connect_IdToken_Release",
|
||||||
|
"EOS_Connect_VerifyIdToken",
|
||||||
|
"EOS_Platform_Tick",
|
||||||
|
"EOS_Lobby_IsLobbyOwner",
|
||||||
|
"EOS_Lobby_GetInviteCount",
|
||||||
|
"EOS_Lobby_CopyInviteIdByIndex",
|
||||||
|
"EOS_Lobby_GetConnectString",
|
||||||
|
"EOS_Lobby_ParseConnectString",
|
||||||
|
"EOS_Platform_GetActiveCountryCode",
|
||||||
|
"EOS_Platform_GetActiveLocaleCode",
|
||||||
|
]
|
||||||
|
|
||||||
|
funcs = []
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
if not line: continue
|
||||||
|
parts = line.split()
|
||||||
|
if len(parts) >= 4:
|
||||||
|
funcs.append(parts[-1])
|
||||||
|
|
||||||
|
with open('proxy_asm.s', 'w') as asm:
|
||||||
|
asm.write('.text\n')
|
||||||
|
for f in funcs:
|
||||||
|
if f not in hooks:
|
||||||
|
asm.write(f'.globl {f}\n')
|
||||||
|
asm.write(f'{f}:\n')
|
||||||
|
asm.write(f' jmp *orig_{f}(%rip)\n\n')
|
||||||
|
|
||||||
|
with open('proxy_pointers.h', 'w') as hdr:
|
||||||
|
hdr.write('extern "C" {\n')
|
||||||
|
for f in funcs:
|
||||||
|
if f not in hooks:
|
||||||
|
hdr.write(f' void* orig_{f} = nullptr;\n')
|
||||||
|
hdr.write('}\n\n')
|
||||||
|
hdr.write('void LoadOriginalFunctions(HMODULE hMod) {\n')
|
||||||
|
for f in funcs:
|
||||||
|
if f not in hooks:
|
||||||
|
hdr.write(f' orig_{f} = (void*)GetProcAddress(hMod, "{f}");\n')
|
||||||
|
hdr.write('}\n')
|
||||||
|
|
||||||
|
with open('proxy.def', 'w') as out:
|
||||||
|
out.write('LIBRARY "EOSSDK-Win64-Shipping.dll"\n')
|
||||||
|
out.write('EXPORTS\n')
|
||||||
|
for f in funcs:
|
||||||
|
out.write(f' {f}\n')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue