You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
9.1 KiB
299 lines
9.1 KiB
#pragma once |
|
|
|
#include <cerrno> |
|
#include <cstdint> |
|
#include <limits> |
|
#include <string> |
|
#include <cstdint> |
|
|
|
#include "appfat.h" |
|
#include "multi.h" |
|
#include "utils/language.h" |
|
#include "utils/stdcompat/string_view.hpp" |
|
|
|
namespace devilution { |
|
|
|
enum game_info : uint8_t { |
|
GAMEINFO_NAME, |
|
GAMEINFO_PASSWORD, |
|
}; |
|
|
|
enum conn_type : uint8_t { |
|
SELCONN_ZT, |
|
SELCONN_TCP, |
|
SELCONN_LOOPBACK, |
|
}; |
|
|
|
extern const char *ConnectionNames[]; |
|
|
|
struct PCXHeader { |
|
uint8_t Manufacturer; |
|
uint8_t Version; |
|
uint8_t Encoding; |
|
uint8_t BitsPerPixel; |
|
uint16_t Xmin; |
|
uint16_t Ymin; |
|
uint16_t Xmax; |
|
uint16_t Ymax; |
|
uint16_t HDpi; |
|
uint16_t VDpi; |
|
uint8_t Colormap[48]; |
|
uint8_t Reserved; |
|
uint8_t NPlanes; |
|
uint16_t BytesPerLine; |
|
uint16_t PaletteInfo; |
|
uint16_t HscreenSize; |
|
uint16_t VscreenSize; |
|
uint8_t Filler[54]; |
|
}; |
|
|
|
struct _SNETCAPS { |
|
uint32_t size; |
|
uint32_t flags; |
|
uint32_t maxmessagesize; |
|
uint32_t maxqueuesize; |
|
uint32_t maxplayers; |
|
uint32_t bytessec; |
|
uint32_t latencyms; |
|
uint32_t defaultturnssec; |
|
uint32_t defaultturnsintransit; |
|
}; |
|
|
|
struct _SNETEVENT { |
|
uint32_t eventid; |
|
uint32_t playerid; |
|
void *data; |
|
uint32_t databytes; |
|
}; |
|
|
|
// Note to self: Linker error => forgot a return value in cpp |
|
|
|
// We declare the StormLib methods we use here. |
|
// StormLib uses the Windows calling convention on Windows for these methods. |
|
#ifdef _WIN32 |
|
#define WINAPI __stdcall |
|
#else |
|
#define WINAPI |
|
#endif |
|
|
|
// Game states |
|
#define GAMESTATE_PRIVATE 0x01 |
|
#define GAMESTATE_FULL 0x02 |
|
#define GAMESTATE_ACTIVE 0x04 |
|
#define GAMESTATE_STARTED 0x08 |
|
#define GAMESTATE_REPLAY 0x80 |
|
|
|
#define PS_CONNECTED 0x10000 |
|
#define PS_TURN_ARRIVED 0x20000 |
|
#define PS_ACTIVE 0x40000 |
|
|
|
#define LEAVE_ENDING 0x40000004 |
|
#define LEAVE_DROP 0x40000006 |
|
|
|
#if defined(__GNUC__) || defined(__cplusplus) |
|
extern "C" { |
|
#endif |
|
|
|
bool SNetCreateGame(const char *pszGameName, const char *pszGamePassword, char *GameTemplateData, int GameTemplateSize, int *playerID); |
|
bool SNetDestroy(); |
|
|
|
/* SNetDropPlayer @ 106 |
|
* |
|
* Drops a player from the current game. |
|
* |
|
* playerid: The player ID for the player to be dropped. |
|
* flags: |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetDropPlayer(int playerid, uint32_t flags); |
|
|
|
/* SNetGetGameInfo @ 107 |
|
* |
|
* Retrieves specific game information from Storm, such as name, password, |
|
* stats, mode, game template, and players. |
|
* |
|
* type: The type of data to retrieve. See GAMEINFO_ flags. |
|
* dst: The destination buffer for the data. |
|
* length: The maximum size of the destination buffer. |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetGetGameInfo(game_info type, void *dst, unsigned int length); |
|
|
|
/* SNetGetTurnsInTransit @ 115 |
|
* |
|
* Retrieves the number of turns (buffers) that have been queued |
|
* before sending them over the network. |
|
* |
|
* turns: A pointer to an integer that will receive the value. |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetGetTurnsInTransit(uint32_t *turns); |
|
|
|
bool SNetJoinGame(char *gameName, char *gamePassword, int *playerid); |
|
|
|
/* SNetLeaveGame @ 119 |
|
* |
|
* Notifies Storm that the player has left the game. Storm will |
|
* notify all connected peers through the network provider. |
|
* |
|
* type: The leave type. It doesn't appear to be important, no documentation available. |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetLeaveGame(int type); |
|
|
|
bool SNetReceiveMessage(int *senderplayerid, void **data, uint32_t *databytes); |
|
bool SNetReceiveTurns(int arraysize, char **arraydata, size_t *arraydatabytes, uint32_t *arrayplayerstatus); |
|
|
|
typedef void (*SEVTHANDLER)(struct _SNETEVENT *); |
|
|
|
/* SNetSendMessage @ 127 |
|
* |
|
* Sends a message to a player given their player ID. Network message |
|
* is sent using class 01 and is retrieved by the other client using |
|
* SNetReceiveMessage(). |
|
* |
|
* playerID: The player index of the player to receive the data. |
|
* Conversely, this field can be one of the following constants: |
|
* SNPLAYER_ALL | Sends the message to all players, including oneself. |
|
* SNPLAYER_OTHERS | Sends the message to all players, except for oneself. |
|
* data: A pointer to the data. |
|
* databytes: The amount of bytes that the data pointer contains. |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetSendMessage(int playerID, void *data, unsigned int databytes); |
|
|
|
// Macro values to target specific players |
|
#define SNPLAYER_ALL -1 |
|
#define SNPLAYER_OTHERS -2 |
|
|
|
#define MPQ_OPEN_READ_ONLY 0x00000100 |
|
#define SFILE_OPEN_FROM_MPQ 0 |
|
#define SFILE_OPEN_LOCAL_FILE 0xFFFFFFFF |
|
|
|
/* SNetSendTurn @ 128 |
|
* |
|
* Sends a turn (data packet) to all players in the game. Network data |
|
* is sent using class 02 and is retrieved by the other client using |
|
* SNetReceiveTurns(). |
|
* |
|
* data: A pointer to the data. |
|
* databytes: The amount of bytes that the data pointer contains. |
|
* |
|
* Returns true if the function was called successfully and false otherwise. |
|
*/ |
|
bool SNetSendTurn(char *data, unsigned int databytes); |
|
|
|
bool SFileOpenFile(const char *filename, HANDLE *phFile); |
|
|
|
// Functions implemented in StormLib |
|
#if defined(_WIN64) || defined(_WIN32) |
|
bool WINAPI SFileOpenArchive(const wchar_t *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); |
|
#else |
|
bool WINAPI SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); |
|
#endif |
|
bool WINAPI SFileCloseArchive(HANDLE hArchive); |
|
bool WINAPI SFileOpenFileEx(HANDLE hMpq, const char *szFileName, DWORD dwSearchScope, HANDLE *phFile); |
|
bool WINAPI SFileReadFile(HANDLE hFile, void *buffer, unsigned int nNumberOfBytesToRead, unsigned int *read, void *lpDistanceToMoveHigh); |
|
DWORD WINAPI SFileGetFileSize(HANDLE hFile, uint32_t *lpFileSizeHigh = nullptr); |
|
DWORD WINAPI SFileSetFilePointer(HANDLE, int, int *, int); |
|
bool WINAPI SFileCloseFile(HANDLE hFile); |
|
|
|
// These error codes are used and returned by StormLib. |
|
// See StormLib/src/StormPort.h |
|
#if defined(_WIN32) |
|
// https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- |
|
#define STORM_ERROR_FILE_NOT_FOUND 2 |
|
#define STORM_ERROR_HANDLE_EOF 38 |
|
#else // !defined(_WIN32) |
|
#define STORM_ERROR_FILE_NOT_FOUND ENOENT |
|
#define STORM_ERROR_HANDLE_EOF 1002 |
|
#endif |
|
|
|
/* SErrGetLastError @ 463 |
|
* |
|
* Retrieves the last error that was specifically |
|
* set for the Storm library. |
|
* |
|
* Returns the last error set within the Storm library. |
|
*/ |
|
uint32_t SErrGetLastError(); |
|
|
|
/* SErrSetLastError @ 465 |
|
* |
|
* Sets the last error for the Storm library and the Kernel32 library. |
|
* |
|
* dwErrCode: The error code that will be set. |
|
*/ |
|
void SErrSetLastError(uint32_t dwErrCode); |
|
|
|
// Values for dwErrCode |
|
#define STORM_ERROR_GAME_TERMINATED 0x85100069 |
|
#define STORM_ERROR_INVALID_PLAYER 0x8510006a |
|
#define STORM_ERROR_NO_MESSAGES_WAITING 0x8510006b |
|
#define STORM_ERROR_NOT_IN_GAME 0x85100070 |
|
|
|
/* SStrCopy @ 501 |
|
* |
|
* Copies a string from src to dest (including NULL terminator) |
|
* until the max_length is reached. |
|
* |
|
* dest: The destination array. |
|
* src: The source array. |
|
* max_length: The maximum length of dest. |
|
* |
|
*/ |
|
void SStrCopy(char *dest, const char *src, int max_length); |
|
|
|
bool SNetGetOwnerTurnsWaiting(uint32_t *); |
|
bool SNetUnregisterEventHandler(event_type); |
|
bool SNetRegisterEventHandler(event_type, SEVTHANDLER); |
|
bool SNetSetBasePlayer(int); |
|
bool SNetInitializeProvider(uint32_t provider, struct GameData *gameData); |
|
void SNetGetProviderCaps(struct _SNETCAPS *); |
|
|
|
#if defined(__GNUC__) || defined(__cplusplus) |
|
} |
|
|
|
// Additions to Storm API: |
|
#if defined(_WIN64) || defined(_WIN32) |
|
// On Windows, handles wchar conversion and calls the wchar version of SFileOpenArchive. |
|
bool SFileOpenArchive(const char *szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE *phMpq); |
|
#endif |
|
|
|
// Locks ReadFile and CloseFile under a mutex. |
|
// See https://github.com/ladislav-zezula/StormLib/issues/175 |
|
bool SFileReadFileThreadSafe(HANDLE hFile, void *buffer, size_t nNumberOfBytesToRead, size_t *read = nullptr, int *lpDistanceToMoveHigh = nullptr); |
|
bool SFileCloseFileThreadSafe(HANDLE hFile); |
|
|
|
// Sets the file's 64-bit seek position. |
|
inline std::uint64_t SFileSetFilePointer(HANDLE hFile, std::int64_t offset, int whence) |
|
{ |
|
int high = static_cast<std::uint64_t>(offset) >> 32; |
|
int low = static_cast<int>(offset); |
|
low = SFileSetFilePointer(hFile, low, &high, whence); |
|
return (static_cast<std::uint64_t>(high) << 32) | low; |
|
} |
|
|
|
// Returns the current 64-bit file seek position. |
|
inline std::uint64_t SFileGetFilePointer(HANDLE hFile) |
|
{ |
|
// We use `SFileSetFilePointer` with offset 0 to get the current position |
|
// because there is no `SFileGetFilePointer`. |
|
return SFileSetFilePointer(hFile, 0, DVL_FILE_CURRENT); |
|
} |
|
|
|
#endif |
|
|
|
void DvlNet_SendInfoRequest(); |
|
void DvlNet_ClearGamelist(); |
|
std::vector<std::string> DvlNet_GetGamelist(); |
|
void DvlNet_SetPassword(std::string pw); |
|
void DvlNet_ClearPassword(); |
|
bool DvlNet_IsPublicGame(); |
|
|
|
} // namespace devilution
|
|
|