Skip to content

Instantly share code, notes, and snippets.

@v1vendi
Created July 27, 2023 19:40
Show Gist options
  • Save v1vendi/14216f28723f5eb7f63f7dd3e96e5cb5 to your computer and use it in GitHub Desktop.
Save v1vendi/14216f28723f5eb7f63f7dd3e96e5cb5 to your computer and use it in GitHub Desktop.
Epic Online Services (EOS) SDK ctypes bindings for python example
import sys
import os
import ctypes
from enum import IntEnum
dir_path = os.path.dirname(os.path.realpath(__file__))
handle = ctypes.CDLL(dir_path + "/../SDK/Bin/libEOSSDK-Mac-Shipping.dylib")
class CtypesEnum(IntEnum):
@classmethod
def from_param(cls, obj):
return int(obj)
EOS_EResult_ToString = handle.EOS_EResult_ToString
EOS_EResult_ToString.restype = ctypes.c_char_p
EOS_EResult_ToString.argtypes = [ctypes.c_int]
class EOS_EpicAccountIdDetails(ctypes.Structure):
pass
EOS_EpicAccountId = ctypes.POINTER(EOS_EpicAccountIdDetails)
# Set the argument and return types for the C functions
handle.EOS_EpicAccountId_ToString.argtypes = [
EOS_EpicAccountId,
ctypes.c_char_p,
ctypes.POINTER(ctypes.c_int32)
]
handle.EOS_EpicAccountId_ToString.restype = ctypes.c_int
handle.EOS_EpicAccountId_FromString.argtypes = [ctypes.c_char_p]
handle.EOS_EpicAccountId_FromString.restype = EOS_EpicAccountId
# Example usage of the C functions
def epic_account_id_to_string(account_id):
buffer_length = 512 # You can adjust this buffer size based on your needs
out_buffer = ctypes.create_string_buffer(buffer_length)
in_out_buffer_length = ctypes.c_int32(buffer_length)
result = handle.EOS_EpicAccountId_ToString(
account_id,
out_buffer,
ctypes.byref(in_out_buffer_length)
)
if result == 0: # 0 indicates success
return out_buffer.value
else:
return None
def epic_account_id_from_string(account_id_string):
return handle.EOS_EpicAccountId_FromString(account_id_string)
def is_valid(account_id):
handle.EOS_EpicAccountId_IsValid.restype = ctypes.c_int
handle.EOS_EpicAccountId_IsValid.argtypes = [EOS_EpicAccountId]
print(handle.EOS_EpicAccountId_IsValid(account_id))
# id = epic_account_id_from_string(b'15e2c4cabad149d69d2b12d3cf06f459')
# print(epic_account_id_to_string(id))
# is_valid(id)
import sys
import os
import ctypes
from enum import IntEnum
from eos_result import *
from eos_common import *
class EOS_ELogLevel(CtypesEnum):
EOS_LOG_Off = 0
EOS_LOG_Fatal = 100
EOS_LOG_Error = 200
EOS_LOG_Warning = 300
EOS_LOG_Info = 400
EOS_LOG_Verbose = 500
EOS_LOG_VeryVerbose = 600
class EOS_ELogCategory(CtypesEnum):
EOS_LC_Core = 0
EOS_LC_Auth = 1
EOS_LC_Friends = 2
EOS_LC_Presence = 3
EOS_LC_UserInfo = 4
EOS_LC_HttpSerialization = 5
EOS_LC_Ecom = 6
EOS_LC_P2P = 7
EOS_LC_Sessions = 8
EOS_LC_RateLimiter = 9
EOS_LC_PlayerDataStorage = 10
EOS_LC_Analytics = 11
EOS_LC_Messaging = 12
EOS_LC_Connect = 13
EOS_LC_Overlay = 14
EOS_LC_Achievements = 15
EOS_LC_Stats = 16
EOS_LC_UI = 17
EOS_LC_Lobby = 18
EOS_LC_Leaderboards = 19
EOS_LC_Keychain = 20
EOS_LC_IntegratedPlatform = 21
EOS_LC_TitleStorage = 22
EOS_LC_Mods = 23
EOS_LC_AntiCheat = 24
EOS_LC_Reports = 25
EOS_LC_Sanctions = 26
EOS_LC_ProgressionSnapshots = 27
EOS_LC_KWS = 28
EOS_LC_RTC = 29
EOS_LC_RTCAdmin = 30
EOS_LC_CustomInvites = 31
EOS_LC_ALL_CATEGORIES = 0x7fffffff
def EOS_Logging_SetLogLevel(LogCategory, LogLevel):
handle.EOS_Logging_SetLogLevel.restype=ctypes.c_int
handle.EOS_Logging_SetLogLevel.argtypes = [EOS_ELogLevel, EOS_ELogCategory]
handle.EOS_Logging_SetLogLevel(LogCategory, LogLevel)
# Define the EOS_LogMessage structure equivalent in Python
class EOS_LogMessage(ctypes.Structure):
_fields_ = [
("Category", ctypes.c_char_p),
("Message", ctypes.c_char_p),
("Level", ctypes.c_int32),
]
EOS_Logging_SetCallback = handle.EOS_Logging_SetCallback
EOS_Logging_SetCallback.restype = ctypes.c_int32
@ctypes.CFUNCTYPE(None, ctypes.POINTER(EOS_LogMessage))
def log_callback(log_message):
# Cast the log_message to the Python equivalent structure
log_message = ctypes.cast(log_message, ctypes.POINTER(EOS_LogMessage)).contents
# Extract the values from the log_message structure
category = log_message.Category.decode('utf-8')
message = log_message.Message.decode('utf-8')
log_level = EOS_ELogLevel(log_message.Level)
# Process the log message as needed (printing it in this case)
print(f"Category: {category}, Message: {message}, Level: {log_level}")
import sys
import os
import ctypes
from enum import IntEnum
from eos_common import *
from eos_logging import *
from eos_result import *
EOS_Logging_SetLogLevel(EOS_ELogCategory.EOS_LC_ALL_CATEGORIES, EOS_ELogLevel.EOS_LOG_VeryVerbose)
class EOS_PlatformHandle(ctypes.Structure): pass
class EOS_Bool(ctypes.c_int32): pass
class EOS_Platform_ClientCredentials(ctypes.Structure):
_fields_ = [
("ClientId", ctypes.c_char_p),
("ClientSecret", ctypes.c_char_p),
]
class EOS_Platform_RTCOptions(ctypes.Structure): pass
class EOS_HIntegratedPlatformOptionsContainer(ctypes.Structure): pass
class EOS_Platform_Options(ctypes.Structure):
_fields_ = [
("ApiVersion", ctypes.c_int32),
("Reserved", ctypes.c_void_p),
("ProductId", ctypes.c_char_p),
("SandboxId", ctypes.c_char_p),
("ClientCredentials", EOS_Platform_ClientCredentials),
("bIsServer", EOS_Bool),
("EncryptionKey", ctypes.c_char_p),
("OverrideCountryCode", ctypes.c_char_p),
("OverrideLocaleCode", ctypes.c_char_p),
("DeploymentId", ctypes.c_char_p),
("Flags", ctypes.c_uint64),
("CacheDirectory", ctypes.c_char_p),
("TickBudgetInMilliseconds", ctypes.c_uint32),
("RTCOptions", ctypes.POINTER(EOS_Platform_RTCOptions)),
("IntegratedPlatformOptionsContainerHandle", ctypes.POINTER(EOS_HIntegratedPlatformOptionsContainer)),
]
# Define the C function pointer types in Python
EOS_AllocateMemoryFunc = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t)
EOS_ReallocateMemoryFunc = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t, ctypes.c_size_t)
EOS_ReleaseMemoryFunc = ctypes.CFUNCTYPE(None, ctypes.c_void_p)
# Define the C structure equivalent in Python
class EOS_Initialize_ThreadAffinity(ctypes.Structure):
_fields_ = [
("ApiVersion", ctypes.c_int32),
("NetworkWork", ctypes.c_uint64),
("StorageIo", ctypes.c_uint64),
("WebSocketIo", ctypes.c_uint64),
("P2PIo", ctypes.c_uint64),
("HttpRequestIo", ctypes.c_uint64),
("RTCIo", ctypes.c_uint64),
]
class EOS_InitializeOptions(ctypes.Structure):
_fields_ = [
("ApiVersion", ctypes.c_int32),
("AllocateMemoryFunction", EOS_AllocateMemoryFunc),
("ReallocateMemoryFunction", EOS_ReallocateMemoryFunc),
("ReleaseMemoryFunction", EOS_ReleaseMemoryFunc),
("ProductName", ctypes.c_char_p),
("ProductVersion", ctypes.c_char_p),
("Reserved", ctypes.c_void_p),
("SystemInitializeOptions", ctypes.c_void_p), # Replace this with the correct type
("OverrideThreadAffinity", ctypes.POINTER(EOS_Initialize_ThreadAffinity)),
]
# Define the EOS_Initialize function prototype in Python
EOS_Initialize = handle.EOS_Initialize
EOS_Initialize.restype = EOS_EResult
EOS_Initialize.argtypes = [ctypes.POINTER(EOS_InitializeOptions)]
# Now you can define the options and use them with EOS_Initialize
options = EOS_InitializeOptions()
options.ApiVersion = 4
options.ProductName = b"YourProductName"
options.ProductVersion = b"YourProductVersion"
options.OverrideThreadAffinity = None # Replace this with the appropriate thread affinity settings
# Set the AllocateMemoryFunction, ReallocateMemoryFunction, and ReleaseMemoryFunction if needed
# options.AllocateMemoryFunction = ...
# options.ReallocateMemoryFunction = ...
# options.ReleaseMemoryFunction = ...
result = EOS_Initialize(ctypes.byref(options))
if result == EOS_EResult.EOS_Success:
print("EOS_Initialize successful.")
else:
print("EOS_Initialize failed.")
print(result)
result = EOS_Logging_SetCallback(log_callback)
if result == EOS_EResult.EOS_Success:
print("Log callback set successfully.")
else:
print("Failed to set log callback.")
print(result)
EOS_Logging_SetLogLevel(EOS_ELogCategory.EOS_LC_ALL_CATEGORIES, EOS_ELogLevel.EOS_LOG_VeryVerbose)
# EOS_HPlatform = ctypes.POINTER(EOS_PlatformHandle)
options = EOS_Platform_Options()
options.ApiVersion = 12
options.ProductId = b"3109f233aa384588b173290a643b49a7"
options.SandboxId = b"1bd04772bbab4581a081163c94f7651e"
options.DeploymentId = b"a544d8d9d0964277afb0d6fcbb345692"
options.ClientCredentials.ClientId = b"xyza7891rUrD6KcKVVmYT59nVMQAFuKj"
options.ClientCredentials.ClientSecret = b"x+BTjdEkKLIBhmESUiSX/Ip3RehB30sUBvpmYi//Z6A"
options.bIsServer = EOS_Bool(1)
options.flags = 0
options.CacheDirectory = b"/temp"
options.EncryptionKey = b"1111111111111111111111111111111111111111111111111111111111111111"
platform = handle.EOS_Platform_Create(options)
# print(platform)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment