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

Port for windows #18

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Expand Up @@ -11,3 +11,9 @@
.cache
.vscode
workspace.code-workspace
.vs
[Ee]xtern
*.wsp

# Visual Studio IDE
CMakeSettings.json
120 changes: 72 additions & 48 deletions CMakeLists.txt
Expand Up @@ -3,64 +3,88 @@ cmake_minimum_required(VERSION 3.16)
# SpadesX
project(SpadesX)

# Find pthread
find_package(Threads REQUIRED)
# Add third party libraries
add_subdirectory(Extern)
add_executable(SpadesX "")

find_package(PkgConfig)
pkg_check_modules(PC_enet QUIET enet)
if(WIN32)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Afaik ByteBit builds it without this mess ? And it works. You are also basically FORCING users to build with Visual Studio on windows. Which i do not like.

if (NOT "${VCPKG_INSTALLED_DIR}" STREQUAL "")
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
find_package(unofficial-enet CONFIG REQUIRED)
find_package(json-c CONFIG REQUIRED)
find_package(PThreads4W REQUIRED)
find_package(unofficial-readline-win32 CONFIG REQUIRED)

find_path(enet_INCLUDE_DIR
NAMES enet/enet.h
PATHS ${PC_enet_INCLUDE_DIRS} ../../deps
PATH_SUFFIXES enet
)
# MSVC emits several warnings when put the /Wall argument, it might not be worth correcting the warnings
# (even because I believe they are not being issued in GCC/Clang (I believe)), i believe /W1 is more than enough for this case
add_compile_options(/W1 /WX /std:c11)

find_library(enet_LIBRARY
NAMES enet
PATHS ${PC_enet_LIBRARY_DIRS} ../../deps
)
set_target_properties(unofficial::enet::enet PROPERTIES
INTERFACE_LINK_LIBRARIES "ws2_32;winmm"
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(enet
FOUND_VAR enet_FOUND
REQUIRED_VARS
enet_LIBRARY
enet_INCLUDE_DIR
)
target_link_libraries(SpadesX
PRIVATE
unofficial::readline-win32::readline
PThreads4W::PThreads4W
json-c::json-c
unofficial::enet::enet
util
mapvxl
)
else()
message(FATAL_ERROR "Sorry, but compiling without MSVC on Windows is not yet supported.")
endif()
else()
message(FATAL_ERROR "Sorry, but compiling using CMake on Windows without VCPKG is not yet supported.")
endif()
else()
# Find pthread
find_package(Threads REQUIRED)

# Add third party libraries
add_subdirectory(Extern)
find_package(PkgConfig)
pkg_check_modules(PC_enet QUIET enet)

# Add main target
add_compile_options(-Wall -Wextra -Werror -Wpedantic -Wno-error=unused-but-set-parameter -Wno-error=pedantic -std=gnu11)
add_executable(SpadesX "")
find_path(enet_INCLUDE_DIR
NAMES enet/enet.h
PATHS ${PC_enet_INCLUDE_DIRS} ../../deps
PATH_SUFFIXES enet
)

find_library(enet_LIBRARY
NAMES enet
PATHS ${PC_enet_LIBRARY_DIRS} ../../deps
)

if (enet_FOUND)
add_library(enet::enet STATIC IMPORTED)
set_target_properties(enet::enet PROPERTIES
IMPORTED_LOCATION ${enet_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${enet_INCLUDE_DIR}
)
if (WIN32)
set_target_properties(enet::enet PROPERTIES
INTERFACE_LINK_LIBRARIES "ws2_32;winmm"
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(enet
FOUND_VAR enet_FOUND
REQUIRED_VARS
enet_LIBRARY
enet_INCLUDE_DIR
)
endif (WIN32)
endif (enet_FOUND)

target_link_libraries(SpadesX
PRIVATE
enet::enet
util
mapvxl
m
json-c
readline
Threads::Threads
)
add_compile_options(-Wall -Wextra -Werror -Wpedantic -Wno-error=unused-but-set-parameter -Wno-error=pedantic -std=gnu11)

if (UNIX)
target_link_libraries(SpadesX PRIVATE bsd)
if (enet_FOUND)
add_library(enet::enet STATIC IMPORTED)
set_target_properties(enet::enet PROPERTIES
IMPORTED_LOCATION ${enet_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${enet_INCLUDE_DIR}
)
endif (enet_FOUND)

target_link_libraries(SpadesX
PRIVATE
enet::enet
util
mapvxl
m
json-c
readline
Threads::Threads
bsd
)
endif()

add_subdirectory(Source)
7 changes: 7 additions & 0 deletions Source/Commands.c
Expand Up @@ -905,7 +905,14 @@ void populateCommands(Server* server)
CommandArray[i].commandDesc,
CommandArray[i].PermLevel);
}

#ifdef WIN32
#pragma warning(disable : 4133)
LL_SORT(server->commandsList, commandCompare);
#pragma warning(default : 4133)
#else
LL_SORT(server->commandsList, commandCompare);
#endif
}

void freeCommands(Server* server)
Expand Down
4 changes: 2 additions & 2 deletions Source/Master.c
Expand Up @@ -67,7 +67,7 @@ int ConnectMaster(Server* server, uint16 port)
return 0;
}

void* keepMasterAlive(void* serverVoid)
void keepMasterAlive(void* serverVoid)
{
Server* server = serverVoid;
while (server->running) {
Expand All @@ -76,7 +76,7 @@ void* keepMasterAlive(void* serverVoid)
if (enet_host_service(server->master.client, &server->master.event, 0) < 0) {
pthread_mutex_lock(&serverLock);
LOG_WARNING("Connection to master server lost. Waiting 30 seconds to reconnect...");
sleep(30);
server_sleep(30);
ConnectMaster(server, server->port);
pthread_mutex_unlock(&serverLock);
}
Expand Down
2 changes: 1 addition & 1 deletion Source/Master.h
Expand Up @@ -6,7 +6,7 @@
#include "Util/Enums.h"
#include "Util/Types.h"

void* keepMasterAlive(void* server);
void keepMasterAlive(void* server);
int ConnectMaster(Server* server, uint16 port);
void updateMaster(Server* server);
#endif
27 changes: 27 additions & 0 deletions Source/Protocol.c
Expand Up @@ -22,10 +22,37 @@
#include <string.h>
#include <time.h>

#ifdef WIN32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Including Windows api just for 1 function call. Like grrrrr. Let migw handle that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define WIN32_LEAN_AND_MEAN and we're good :)

#include <Windows.h>

#define POW10_7 10000000
#define DELTA_EPOCH_IN_100NS INT64_C(116444736000000000)
#endif

uint64 getNanos(void)
{
struct timespec ts;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Leave it as it is. It works on windows as it is. Adds pointless complexity.

You literally just copied what mingw does in the clock_gettime functions. Like why ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clock_gettime is a POSIX function, not from Windows

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since mingw is ok with it, perhaps wrap it in #ifdef MSVC ot something

#ifdef WIN32
// https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-libraries/winpthreads/src/clock.c#L121

unsigned __int64 t;

union
{
unsigned __int64 u64;
FILETIME ft;
} ct;

GetSystemTimeAsFileTime(&ct.ft);

t = ct.u64 - DELTA_EPOCH_IN_100NS;
ts.tv_sec = t / POW10_7;
ts.tv_nsec = ((int) (t % POW10_7)) * 100;
#else
clock_gettime(CLOCK_REALTIME, &ts);
#endif

return (uint64) ts.tv_sec * 1000000000L + ts.tv_nsec;
}

Expand Down
34 changes: 24 additions & 10 deletions Source/Server.c
Expand Up @@ -18,6 +18,7 @@
#include "Util/Queue.h"
#include "Util/Types.h"
#include "Util/Utlist.h"
#include "Util/Functions.h"
#include "../Extern/libmapvxl/libmapvxl.h"

#include <enet/enet.h>
Expand All @@ -35,7 +36,13 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef WIN32
#include <io.h>
#include <Windows.h>
#else
#include <unistd.h>
#endif

Server server;
pthread_mutex_t serverLock;
Expand Down Expand Up @@ -522,10 +529,12 @@ void ReadlineNewLine(int signal)
ctrlc = 1;
printf("\n");
LOG_INFO("Are you sure you want to exit? (Y/n)");

if (write(STDIN_FILENO, "\n", sizeof("\n")) != sizeof("\n")) {

// 0 = STDIN_FILENO
if (write(0, "\n", sizeof("\n")) != sizeof("\n")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Just hell no. If it doesnt exist on windows. Define it.

LOG_DEBUG("epic write fail");
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pointless new line

rl_replace_line("", 0);
rl_on_new_line();
rl_redisplay();
Expand All @@ -536,7 +545,7 @@ void StopServer()
server.running = 0;
}

static void* serverConsole(void* arg)
static void serverConsole(void* arg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave it as pointer please. Dont pretype it in the actual passtrough.

{
(void) arg;
char* buf;
Expand All @@ -555,16 +564,21 @@ static void* serverConsole(void* arg)
}
free(buf);
}

#ifdef WIN32
clear_history();
#else
rl_clear_history();
#endif

StopServer();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed at all. Like it was there before. Rebase your commits. Dont fix up in later ones :|


sleep(5); // wait 5 seconds for the server to stop
server_sleep(5); // wait 5 seconds for the server to stop

// if this thread is not dead at this point, then we need to stop the server by force >:)
LOG_ERROR("Server did not respond for 5 seconds. Killing it with fire...");

exit(-1);

return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ?

}

void StartServer(uint16 port,
Expand Down Expand Up @@ -656,12 +670,12 @@ void StartServer(uint16 port,
server.master.timeSinceLastSend = time(NULL);

pthread_t masterThread;
pthread_create(&masterThread, NULL, keepMasterAlive, (void*)&server);
pthread_create(&masterThread, NULL, (void*)keepMasterAlive, (void*)&server);
pthread_detach(masterThread);

rl_catch_signals = 0;
rl_catch_signals = 0;
pthread_t console;
pthread_create(&console, NULL, serverConsole, NULL);
pthread_create(&console, NULL, (void*)serverConsole, NULL);
pthread_detach(console);

signal(SIGINT, ReadlineNewLine);
Expand All @@ -673,7 +687,7 @@ void StartServer(uint16 port,
WorldUpdate();
forPlayers();
pthread_mutex_unlock(&serverLock);
sleep(0);
server_sleep(0);
}
while (server.map.compressedMap) {
server.map.compressedMap = Pop(server.map.compressedMap);
Expand Down
4 changes: 4 additions & 0 deletions Source/Server.h
Expand Up @@ -15,6 +15,10 @@
#define DEFAULT_SERVER_PORT 32887
#endif

#ifdef WIN32
#include <pthread.h>
#endif

extern pthread_mutex_t serverLock;

Server* getServer();
Expand Down
33 changes: 26 additions & 7 deletions Source/Util/CMakeLists.txt
Expand Up @@ -11,28 +11,47 @@ set(UTIL_HEADERS
Types.h
Physics.h
Line.h
)
Functions.h)

set(UTIL_SOURCES
Queue.c
Compress.c
DataStream.c
Physics.c
Line.c
)
Functions.c)

target_sources(util
PRIVATE
${UTIL_SOURCES}
${UTIL_HEADERS}
)
)

target_include_directories(util
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)

target_link_libraries(util
PRIVATE
z # zlib
)
if(WIN32)
if (NOT "${VCPKG_INSTALLED_DIR}" STREQUAL "")
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
find_package(unofficial-enet CONFIG REQUIRED)
find_package(ZLIB REQUIRED)

target_link_libraries(util
PRIVATE
ZLIB::ZLIB
unofficial::enet::enet
)
else()
message(FATAL_ERROR "Sorry, but compiling without MSVC on Windows is not yet supported.")
endif()
else()
message(FATAL_ERROR "Sorry, but compiling using CMake on Windows without VCPKG is not yet supported.")
endif()
else()
target_link_libraries(util
PRIVATE
z # zlib
)
endif()
1 change: 0 additions & 1 deletion Source/Util/Compress.c
Expand Up @@ -7,7 +7,6 @@
#include <stdlib.h>
#include <zlib.h>


static z_stream* GlobalCompressor = NULL;

int InitCompressor(int level)
Expand Down