From 282ac22a460d5f6891e75296d76f0c929069028c Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 12 Jan 2020 14:28:57 -0500 Subject: [PATCH 01/10] Use the better api for linux controller support and include it in the auto builds. --- build_steamos.sh | 8 +- controller/gamepad.c | 519 +++++++++++++++++++++------------- controller/gamepad.h | 3 +- dll/steam_controller.h | 9 +- scripts/steamclient_loader.sh | 18 +- 5 files changed, 354 insertions(+), 203 deletions(-) mode change 100644 => 100755 scripts/steamclient_loader.sh diff --git a/build_steamos.sh b/build_steamos.sh index ef0423e..c91e44b 100755 --- a/build_steamos.sh +++ b/build_steamos.sh @@ -7,10 +7,10 @@ mkdir -p linux/tools cp scripts/find_interfaces.sh linux/tools/ cp scripts/steamclient_loader.sh linux/tools/ ../protobuf/prefix_x86/bin/protoc -I./dll/ --cpp_out=./dll/ ./dll/*.proto -g++ -m32 -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -s -o linux/x86/libsteam_api.so dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix_x86/include/ -L../protobuf/prefix_x86/lib/ -lprotobuf-lite -std=c++11 && echo built32 +g++ -m32 -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -DCONTROLLER_SUPPORT -s -o linux/x86/libsteam_api.so dll/*.cpp dll/*.cc controller/*.c -Wno-return-type -I../protobuf/prefix_x86/include/ -L../protobuf/prefix_x86/lib/ -lprotobuf-lite -std=c++11 && echo built32 g++ -m32 -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -DNO_DISK_WRITES -DLOBBY_CONNECT -s -o linux/lobby_connect/lobby_connect_x86 lobby_connect.cpp dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix_x86/include/ -L../protobuf/prefix_x86/lib/ -lprotobuf-lite -lpthread -std=c++11 && echo built_lobby_connect32 -g++ -m32 -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DSTEAMCLIENT_DLL -DNDEBUG -s -o linux/x86/steamclient.so dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix_x86/include/ -L../protobuf/prefix_x86/lib/ -lprotobuf-lite -std=c++11 && echo built32_steamclient +g++ -m32 -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DSTEAMCLIENT_DLL -DNDEBUG -DCONTROLLER_SUPPORT -s -o linux/x86/steamclient.so dll/*.cpp dll/*.cc controller/*.c -Wno-return-type -I../protobuf/prefix_x86/include/ -L../protobuf/prefix_x86/lib/ -lprotobuf-lite -std=c++11 && echo built32_steamclient ../protobuf/prefix/bin/protoc -I./dll/ --cpp_out=./dll/ ./dll/*.proto -g++ -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -s -o linux/x86_64/libsteam_api.so dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix/include/ -L../protobuf/prefix/lib/ -lprotobuf-lite -std=c++11 && echo built64 +g++ -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -DCONTROLLER_SUPPORT -s -o linux/x86_64/libsteam_api.so dll/*.cpp dll/*.cc controller/*.c -Wno-return-type -I../protobuf/prefix/include/ -L../protobuf/prefix/lib/ -lprotobuf-lite -std=c++11 && echo built64 g++ -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DNDEBUG -DNO_DISK_WRITES -DLOBBY_CONNECT -s -o linux/lobby_connect/lobby_connect_x64 lobby_connect.cpp dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix/include/ -L../protobuf/prefix/lib/ -lprotobuf-lite -lpthread -std=c++11 && echo built_lobby_connect64 -g++ -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DSTEAMCLIENT_DLL -DNDEBUG -s -o linux/x86_64/steamclient.so dll/*.cpp dll/*.cc -Wno-return-type -I../protobuf/prefix/include/ -L../protobuf/prefix/lib/ -lprotobuf-lite -std=c++11 && echo built64_steamclient +g++ -shared -fPIC -fvisibility=hidden -Wl,--exclude-libs,ALL -DGNUC -DEMU_RELEASE_BUILD -DSTEAMCLIENT_DLL -DNDEBUG -DCONTROLLER_SUPPORT -s -o linux/x86_64/steamclient.so dll/*.cpp dll/*.cc controller/*.c -Wno-return-type -I../protobuf/prefix/include/ -L../protobuf/prefix/lib/ -lprotobuf-lite -std=c++11 && echo built64_steamclient diff --git a/controller/gamepad.c b/controller/gamepad.c index f1e7893..d9218ed 100644 --- a/controller/gamepad.c +++ b/controller/gamepad.c @@ -25,7 +25,9 @@ # include # include # include -# include +# include +# include +# include #else # error "Unknown platform in gamepad.c" #endif @@ -60,6 +62,8 @@ struct GAMEPAD_STATE { char* device; int fd; int effect; + double axis_min[ABS_MAX]; + double axis_max[ABS_MAX]; #endif }; @@ -126,7 +130,8 @@ void GamepadShutdown(void) { /* no Win32 shutdown required */ } -void GamepadSetRumble(GAMEPAD_DEVICE gamepad, float left, float right) { +void GamepadSetRumble(GAMEPAD_DEVICE gamepad, float left, float right, unsigned int rumble_length_ms) { + //TODO: rumble_length_ms if ((STATE[gamepad].flags & FLAG_RUMBLE) != 0) { XINPUT_VIBRATION vib; ZeroMemory(&vib, sizeof(vib)); @@ -137,14 +142,103 @@ void GamepadSetRumble(GAMEPAD_DEVICE gamepad, float left, float right) { } #elif defined(__linux__) +#define test_bit(nr, addr) \ + (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0) +#define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1) -/* UDev handles */ -static struct udev* UDEV = NULL; -static struct udev_monitor* MON = NULL; + +static int IsGamepad(int fd, char *namebuf, const size_t namebuflen) +{ + struct input_id inpid; + //uint16_t *guid16 = (uint16_t *)guid->data; + + /* When udev is enabled we only get joystick devices here, so there's no need to test them */ + unsigned long evbit[NBITS(EV_MAX)] = { 0 }; + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + + if ((ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) < 0)) { + return (0); + } + + if (!(test_bit(EV_KEY, evbit) && test_bit(EV_ABS, evbit) && + test_bit(ABS_X, absbit) && test_bit(ABS_Y, absbit))) { + return 0; + } + + if (ioctl(fd, EVIOCGNAME(namebuflen), namebuf) < 0) { + return 0; + } + + if (ioctl(fd, EVIOCGID, &inpid) < 0) { + return 0; + } + + //printf("Joystick: %s, bustype = %d, vendor = 0x%.4x, product = 0x%.4x, version = %d\n", namebuf, inpid.bustype, inpid.vendor, inpid.product, inpid.version); + + //memset(guid->data, 0, sizeof(guid->data)); + + /* We only need 16 bits for each of these; space them out to fill 128. */ + /* Byteswap so devices get same GUID on little/big endian platforms. */ +/* + *guid16++ = SDL_SwapLE16(inpid.bustype); + *guid16++ = 0; + + if (inpid.vendor && inpid.product) { + *guid16++ = SDL_SwapLE16(inpid.vendor); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(inpid.product); + *guid16++ = 0; + *guid16++ = SDL_SwapLE16(inpid.version); + *guid16++ = 0; + } else { + strlcpy((char*)guid16, namebuf, sizeof(guid->data) - 4); + } + + if (SDL_ShouldIgnoreJoystick(namebuf, *guid)) { + return 0; + } +*/ + return 1; +} static void GamepadAddDevice(const char* devPath); static void GamepadRemoveDevice(const char* devPath); +static void GamepadDetect() +{ + DIR *folder; + struct dirent *dent; + + folder = opendir("/dev/input"); + if (folder) { + while ((dent = readdir(folder))) { + int len = strlen(dent->d_name); + if (len > 5 && strncmp(dent->d_name, "event", 5) == 0) { + char path[PATH_MAX]; + snprintf(path, sizeof(path), "/dev/input/%s", dent->d_name); + GamepadAddDevice(path); + } + } + + closedir(folder); + } + + for (int i = 0; i != GAMEPAD_COUNT; ++i) { + if ((STATE[i].flags & FLAG_CONNECTED) && STATE[i].device) { + struct stat sb; + //printf("%s\n", STATE[i].device); + if (stat(STATE[i].device, &sb) == -1) { + GamepadRemoveDevice(STATE[i].device); + } + } + } +} + + + /* Helper to add a new device */ static void GamepadAddDevice(const char* devPath) { int i; @@ -154,11 +248,25 @@ static void GamepadAddDevice(const char* devPath) { if ((STATE[i].flags & FLAG_CONNECTED) == 0) { break; } + + if (STATE[i].device && strcmp(devPath, STATE[i].device) == 0) { + return; + } } + if (i == GAMEPAD_COUNT) { return; } + int fd = open(devPath, O_RDWR, 0); + if (fd < 0) return; + char namebuf[128]; + int is_gamepad = IsGamepad(fd, namebuf, sizeof (namebuf)); + if (!is_gamepad) { + close(fd); + return; + } + /* copy the device path */ STATE[i].device = strdup(devPath); if (STATE[i].device == NULL) { @@ -168,25 +276,87 @@ static void GamepadAddDevice(const char* devPath) { /* reset device state */ GamepadResetState((GAMEPAD_DEVICE)i); - /* attempt to open the device in read-write mode, which we need fo rumble */ - STATE[i].fd = open(STATE[i].device, O_RDWR|O_NONBLOCK); - if (STATE[i].fd != -1) { - STATE[i].flags = FLAG_CONNECTED|FLAG_RUMBLE; - return; - } + fcntl(fd, F_SETFL, O_NONBLOCK); + STATE[i].fd = fd; + STATE[i].flags |= FLAG_CONNECTED; - /* attempt to open in read-only mode if access was denied */ - if (errno == EACCES) { - STATE[i].fd = open(STATE[i].device, O_RDONLY|O_NONBLOCK); - if (STATE[i].fd != -1) { - STATE[i].flags = FLAG_CONNECTED; - return; + int controller = i; + { + int i, t; + unsigned long keybit[NBITS(KEY_MAX)] = { 0 }; + unsigned long absbit[NBITS(ABS_MAX)] = { 0 }; + unsigned long relbit[NBITS(REL_MAX)] = { 0 }; + unsigned long ffbit[NBITS(FF_MAX)] = { 0 }; + + /* See if this device uses the new unified event API */ + if ((ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit) >= 0) && + (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(relbit)), relbit) >= 0)) { + + /* Get the number of buttons, axes, and other thingamajigs */ + for (i = BTN_JOYSTICK; i < KEY_MAX; ++i) { + if (test_bit(i, keybit)) { + //printf("Joystick has button: 0x%x\n", i); + } + } + for (i = 0; i < BTN_JOYSTICK; ++i) { + if (test_bit(i, keybit)) { + //printf("Joystick has button: 0x%x\n", i); + } + } + for (i = 0; i < ABS_MAX; ++i) { + /* Skip hats */ + if (i == ABS_HAT0X) { + i = ABS_HAT3Y; + continue; + } + if (test_bit(i, absbit)) { + struct input_absinfo absinfo; + + if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) { + continue; + } +/* + printf("Joystick has absolute axis: 0x%.2x\n", i); + printf("Values = { %d, %d, %d, %d, %d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat); +*/ + STATE[controller].axis_min[i] = absinfo.minimum; + STATE[controller].axis_max[i] = absinfo.maximum; + } + } + for (i = ABS_HAT0X; i <= ABS_HAT3Y; i += 2) { + if (test_bit(i, absbit) || test_bit(i + 1, absbit)) { + struct input_absinfo absinfo; + int hat_index = (i - ABS_HAT0X) / 2; + + if (ioctl(fd, EVIOCGABS(i), &absinfo) < 0) { + continue; + } +/* + printf("Joystick has hat %d\n", hat_index); + printf("Values = { %d, %d, %d, %d, %d }\n", + absinfo.value, absinfo.minimum, absinfo.maximum, + absinfo.fuzz, absinfo.flat); +*/ + //joystick->hwdata->hats_indices[joystick->nhats++] = hat_index; + } + } + if (test_bit(REL_X, relbit) || test_bit(REL_Y, relbit)) { + //++joystick->nballs; } } - /* could not open the device at all */ - free(STATE[i].device); - STATE[i].device = NULL; + if (ioctl(fd, EVIOCGBIT(EV_FF, sizeof(ffbit)), ffbit) >= 0) { + if (test_bit(FF_RUMBLE, ffbit)) { + STATE[controller].flags |= FLAG_RUMBLE; + } + if (test_bit(FF_SINE, ffbit)) { + //printf("sine\n"); + } + } + } } /* Helper to remove a device */ @@ -218,158 +388,144 @@ void GamepadInit(void) { STATE[i].fd = STATE[i].effect = -1; } - /* open the udev handle */ - UDEV = udev_new(); - if (UDEV == NULL) { - /* FIXME: flag error? */ - return; - } - - /* open monitoring device (safe to fail) */ - MON = udev_monitor_new_from_netlink(UDEV, "udev"); - /* FIXME: flag error if hot-plugging can't be supported? */ - if (MON != NULL) { - udev_monitor_enable_receiving(MON); - udev_monitor_filter_add_match_subsystem_devtype(MON, "input", NULL); - } - - /* enumerate joypad devices */ - enu = udev_enumerate_new(UDEV); - udev_enumerate_add_match_subsystem(enu, "input"); - udev_enumerate_scan_devices(enu); - devices = udev_enumerate_get_list_entry(enu); - - udev_list_entry_foreach(item, devices) { - const char* name; - const char* sysPath; - const char* devPath; - struct udev_device* dev; - - name = udev_list_entry_get_name(item); - dev = udev_device_new_from_syspath(UDEV, name); - sysPath = udev_device_get_syspath(dev); - devPath = udev_device_get_devnode(dev); - - if (sysPath != NULL && devPath != NULL && strstr(sysPath, "/js") != 0) { - GamepadAddDevice(devPath); - } - - udev_device_unref(dev); - } - - /* cleanup */ - udev_enumerate_unref(enu); + GamepadDetect(); } void GamepadUpdate(void) { - if (MON != NULL) { - fd_set r; - struct timeval tv; - int fd = udev_monitor_get_fd(MON); + static unsigned long last = 0; + unsigned long cur = time(NULL); - /* set up a poll on the udev device */ - FD_ZERO(&r); - FD_SET(fd, &r); - - tv.tv_sec = 0; - tv.tv_usec = 0; - - select(fd + 1, &r, 0, 0, &tv); - - /* test if we have a device change */ - if (FD_ISSET(fd, &r)) { - struct udev_device* dev = udev_monitor_receive_device(MON); - if (dev) { - const char* devNode = udev_device_get_devnode(dev); - const char* sysPath = udev_device_get_syspath(dev); - const char* action = udev_device_get_action(dev); - sysPath = udev_device_get_syspath(dev); - action = udev_device_get_action(dev); - - if (strstr(sysPath, "/js") != 0) { - if (strcmp(action, "remove") == 0) { - GamepadRemoveDevice(devNode); - } else if (strcmp(action, "add") == 0) { - GamepadAddDevice(devNode); - } - } - - udev_device_unref(dev); - } - } + if (last + 2 < cur) { + GamepadDetect(); + last = cur; } GamepadUpdateCommon(); } +static int adjust_values_trigger(double min, double max, double value) +{ + return (((value + (0 - min)) / (max - min)) * 255.0); +} + +static int adjust_values_stick(double min, double max, double value) +{ + return (((value + (0 - min)) / (max - min)) * (65535.0)) - 32768.0; +} + static void GamepadUpdateDevice(GAMEPAD_DEVICE gamepad) { if (STATE[gamepad].flags & FLAG_CONNECTED) { - struct js_event je; - while (read(STATE[gamepad].fd, &je, sizeof(je)) > 0) { - int button; - switch (je.type) { - case JS_EVENT_BUTTON: - /* determine which button the event is for */ - switch (je.number) { - case 0: button = BUTTON_A; break; - case 1: button = BUTTON_B; break; - case 2: button = BUTTON_X; break; - case 3: button = BUTTON_Y; break; - case 4: button = BUTTON_LEFT_SHOULDER; break; - case 5: button = BUTTON_RIGHT_SHOULDER; break; - case 6: button = BUTTON_BACK; break; - case 7: button = BUTTON_START; break; - case 8: button = 0; break; /* XBOX button */ - case 9: button = BUTTON_LEFT_THUMB; break; - case 10: button = BUTTON_RIGHT_THUMB; break; - default: button = 0; break; - } + struct input_event events[32]; + int i, len; + int code; - /* set or unset the button */ - if (je.value) { - STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(button); - } else { - STATE[gamepad].bCurrent ^= BUTTON_TO_FLAG(button); - } - - break; - case JS_EVENT_AXIS: - /* normalize and store the axis */ - switch (je.number) { - case 0: STATE[gamepad].stick[STICK_LEFT].x = je.value; break; - case 1: STATE[gamepad].stick[STICK_LEFT].y = -je.value; break; - case 2: STATE[gamepad].trigger[TRIGGER_LEFT].value = (je.value + 32768) >> 8; break; - case 3: STATE[gamepad].stick[STICK_RIGHT].x = je.value; break; - case 4: STATE[gamepad].stick[STICK_RIGHT].y = -je.value; break; - case 5: STATE[gamepad].trigger[TRIGGER_RIGHT].value = (je.value + 32768) >> 8; break; - case 6: - if (je.value == -32767) { - STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_LEFT); - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); - } else if (je.value == 32767) { - STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_LEFT); + while ((len = read(STATE[gamepad].fd, events, (sizeof events))) > 0) { + len /= sizeof(events[0]); + for (i = 0; i < len; ++i) { + int button = 0; + code = events[i].code; + switch (events[i].type) { + case EV_KEY: + //printf("EV_KEY %i\n", code); + switch (code) { + case BTN_SOUTH: button = BUTTON_A; break; + case BTN_EAST: button = BUTTON_B; break; + case BTN_NORTH: button = BUTTON_X; break; + case BTN_WEST: button = BUTTON_Y; break; + case BTN_TL: button = BUTTON_LEFT_SHOULDER; break; + case BTN_TR: button = BUTTON_RIGHT_SHOULDER; break; + case BTN_SELECT: button = BUTTON_BACK; break; + case BTN_START: button = BUTTON_START; break; + case BTN_MODE: button = 0; break; /* XBOX button */ + case BTN_THUMBL: button = BUTTON_LEFT_THUMB; break; + case BTN_THUMBR: button = BUTTON_RIGHT_THUMB; break; + default: button = 0; break; + } + if (events[i].value) { + STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(button); } else { - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_LEFT) & ~BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); + STATE[gamepad].bCurrent ^= BUTTON_TO_FLAG(button); } break; - case 7: - if (je.value == -32767) { - STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_UP); - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); - } else if (je.value == 32767) { - STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_UP); - } else { - STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_UP) & ~BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); + case EV_ABS: + switch (code) { + case ABS_HAT0X: + case ABS_HAT0Y: + case ABS_HAT1X: + case ABS_HAT1Y: + case ABS_HAT2X: + case ABS_HAT2Y: + case ABS_HAT3X: + case ABS_HAT3Y: + //code -= ABS_HAT0X; + //printf("ABS_HAT %i\n", code); + switch(code) { + case ABS_HAT0X: + if (events[i].value < 0) { + STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_LEFT); + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); + } else if (events[i].value > 0) { + STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_LEFT); + } else { + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_LEFT) & ~BUTTON_TO_FLAG(BUTTON_DPAD_RIGHT); + } + break; + case ABS_HAT0Y: + if (events[i].value < 0) { + STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_UP); + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); + } else if (events[i].value > 0) { + STATE[gamepad].bCurrent |= BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_UP); + } else { + STATE[gamepad].bCurrent &= ~BUTTON_TO_FLAG(BUTTON_DPAD_UP) & ~BUTTON_TO_FLAG(BUTTON_DPAD_DOWN); + } + break; + } + break; + default: + //printf("EV_ABS %i %i\n", code, events[i].value); + if (code == ABS_Z || code == ABS_RZ) { + int value = adjust_values_trigger(STATE[gamepad].axis_min[code], STATE[gamepad].axis_max[code], events[i].value); + switch(code) { + case ABS_Z : STATE[gamepad].trigger[TRIGGER_LEFT].value = value; break; + case ABS_RZ: STATE[gamepad].trigger[TRIGGER_RIGHT].value = value; break; + } + } else { + int value = adjust_values_stick(STATE[gamepad].axis_min[code], STATE[gamepad].axis_max[code], events[i].value); + switch(code) { + case ABS_X : STATE[gamepad].stick[STICK_LEFT].x = value; break; + case ABS_Y : STATE[gamepad].stick[STICK_LEFT].y = -value; break; + case ABS_RX: STATE[gamepad].stick[STICK_RIGHT].x = value; break; + case ABS_RY: STATE[gamepad].stick[STICK_RIGHT].y = -value; break; + } + } + break; } break; - default: break; + case EV_REL: + switch (code) { + case REL_X: + case REL_Y: + code -= REL_X; + //printf("EV_REL %i %i\n", code, events[i].value); + break; + default: + break; + } + break; + case EV_SYN: + switch (code) { + case SYN_DROPPED : + //printf("Event SYN_DROPPED detected\n"); + break; + default: + break; + } + default: + break; } - - break; - default: - break; } } } @@ -378,10 +534,6 @@ static void GamepadUpdateDevice(GAMEPAD_DEVICE gamepad) { void GamepadShutdown(void) { int i; - /* cleanup udev */ - udev_monitor_unref(MON); - udev_unref(UDEV); - /* cleanup devices */ for (i = 0; i != GAMEPAD_COUNT; ++i) { if (STATE[i].device != NULL) { @@ -394,47 +546,30 @@ void GamepadShutdown(void) { } } -void GamepadSetRumble(GAMEPAD_DEVICE gamepad, float left, float right) { +void GamepadSetRumble(GAMEPAD_DEVICE gamepad, float left, float right, unsigned int rumble_length_ms) { if (STATE[gamepad].fd != -1) { struct input_event play; + struct ff_effect ff; - /* delete any existing effect */ - if (STATE[gamepad].effect != -1) { - /* stop the effect */ - play.type = EV_FF; - play.code = STATE[gamepad].effect; - play.value = 0; + /* define an effect for this rumble setting */ + ff.type = FF_RUMBLE; + ff.id = STATE[gamepad].effect; + ff.u.rumble.strong_magnitude = (unsigned short)(left * 65535); + ff.u.rumble.weak_magnitude = (unsigned short)(right * 65535); + ff.replay.length = rumble_length_ms; + ff.replay.delay = 0; - write(STATE[gamepad].fd, (const void*)&play, sizeof(play)); - - /* delete the effect */ - ioctl(STATE[gamepad].fd, EVIOCRMFF, STATE[gamepad].effect); + /* upload the effect */ + if (ioctl(STATE[gamepad].fd, EVIOCSFF, &ff) != -1) { + STATE[gamepad].effect = ff.id; } - /* if rumble parameters are non-zero, start the new effect */ - if (left != 0.f || right != 0.f) { - struct ff_effect ff; + /* play the effect */ + play.type = EV_FF; + play.code = STATE[gamepad].effect; + play.value = 1; - /* define an effect for this rumble setting */ - ff.type = FF_RUMBLE; - ff.id = -1; - ff.u.rumble.strong_magnitude = (unsigned short)(left * 65535); - ff.u.rumble.weak_magnitude = (unsigned short)(right * 65535); - ff.replay.length = 5; - ff.replay.delay = 0; - - /* upload the effect */ - if (ioctl(STATE[gamepad].fd, EVIOCSFF, &ff) != -1) { - STATE[gamepad].effect = ff.id; - } - - /* play the effect */ - play.type = EV_FF; - play.code = STATE[gamepad].effect; - play.value = 1; - - write(STATE[gamepad].fd, (const void*)&play, sizeof(play)); - } + write(STATE[gamepad].fd, (const void*)&play, sizeof(play)); } } diff --git a/controller/gamepad.h b/controller/gamepad.h index 4883a3f..0b10143 100644 --- a/controller/gamepad.h +++ b/controller/gamepad.h @@ -232,8 +232,9 @@ GAMEPAD_API GAMEPAD_BOOL GamepadTriggerReleased(GAMEPAD_DEVICE device, GAMEPAD_T * \param device The device to update. * \param left Left motor strengh (0 to 1). * \param right Right motor strengh (0 to 1). + * \param rumble_length_ms rumble time in ms (0 = unlimited). */ -GAMEPAD_API void GamepadSetRumble(GAMEPAD_DEVICE device, float left, float right); +GAMEPAD_API void GamepadSetRumble(GAMEPAD_DEVICE device, float left, float right, unsigned int rumble_length_ms); /** * Query the position of an analog stick as raw values. diff --git a/dll/steam_controller.h b/dll/steam_controller.h index 613da65..f999987 100644 --- a/dll/steam_controller.h +++ b/dll/steam_controller.h @@ -692,7 +692,7 @@ int GetAnalogActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t ac void StopAnalogActionMomentum( ControllerHandle_t controllerHandle, ControllerAnalogActionHandle_t eAction ) { - PRINT_DEBUG("Steam_Controller::StopAnalogActionMomentum\n"); + PRINT_DEBUG("Steam_Controller::StopAnalogActionMomentum %llu %llu\n", controllerHandle, eAction); } @@ -723,7 +723,12 @@ void TriggerVibration( ControllerHandle_t controllerHandle, unsigned short usLef auto controller = controllers.find(controllerHandle); if (controller == controllers.end()) return; - GamepadSetRumble((GAMEPAD_DEVICE)(controllerHandle - 1), ((double)usLeftSpeed) / 65535.0, ((double)usRightSpeed) / 65535.0); + unsigned int rumble_length_ms = 0; +#if defined(__linux__) + //FIXME: shadow of the tomb raider on linux doesn't seem to turn off the rumble so I made it expire after 100ms. Need to check if this is how linux steam actually behaves. + rumble_length_ms = 100; +#endif + GamepadSetRumble((GAMEPAD_DEVICE)(controllerHandle - 1), ((double)usLeftSpeed) / 65535.0, ((double)usRightSpeed) / 65535.0, rumble_length_ms); } diff --git a/scripts/steamclient_loader.sh b/scripts/steamclient_loader.sh old mode 100644 new mode 100755 index 4ef3cb6..0c10d5d --- a/scripts/steamclient_loader.sh +++ b/scripts/steamclient_loader.sh @@ -1,10 +1,15 @@ #!/bin/bash -APP_PATH=./example_executable +APP_NAME="bin/test_executable" APP_ID=480 +APP_PATH=$(dirname "$0") +CONFIG_PATH=$(dirname "$0") -set -e +CUR_DIR=$(pwd) +cd "$CONFIG_PATH" mkdir -p ~/.steam/sdk64 mkdir -p ~/.steam/sdk32 +rm -rf ~/.steam/sdk64/steam_settings +rm -rf ~/.steam/sdk32/steam_settings #make a backup of original files mv ~/.steam/steam.pid ~/.steam/steam.pid.orig || true mv ~/.steam/sdk64/steamclient.so ~/.steam/sdk64/steamclient.so.orig || true @@ -12,13 +17,18 @@ mv ~/.steam/sdk32/steamclient.so ~/.steam/sdk32/steamclient.so.orig || true #copy our files cp x86/steamclient.so ~/.steam/sdk32/steamclient.so cp x86_64/steamclient.so ~/.steam/sdk64/steamclient.so +cp -r steam_settings ~/.steam/sdk32/ +cp -r steam_settings ~/.steam/sdk64/ echo $BASHPID > ~/.steam/steam.pid -SteamAppId=$APP_ID SteamGameId=$APP_ID $APP_PATH - +cd "$APP_PATH" +SteamAppId=$APP_ID SteamGameId=$APP_ID "$APP_NAME" +cd "$CUR_DIR" #restore original rm -f ~/.steam/steam.pid rm -f ~/.steam/sdk64/steamclient.so rm -f ~/.steam/sdk32/steamclient.so +rm -rf ~/.steam/sdk64/steam_settings +rm -rf ~/.steam/sdk32/steam_settings mv ~/.steam/steam.pid.orig ~/.steam/steam.pid mv ~/.steam/sdk64/steamclient.so.orig ~/.steam/sdk64/steamclient.so || true mv ~/.steam/sdk32/steamclient.so.orig ~/.steam/sdk32/steamclient.so || true From 106fb03bb04a38b7836408a47d3163d0c83d26fe Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Sun, 12 Jan 2020 14:43:25 -0500 Subject: [PATCH 02/10] Fix build issue. --- dll/steam_controller.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dll/steam_controller.h b/dll/steam_controller.h index f999987..5b9240a 100644 --- a/dll/steam_controller.h +++ b/dll/steam_controller.h @@ -661,8 +661,8 @@ int GetAnalogActionOrigins( InputHandle_t inputHandle, InputActionSetHandle_t ac if (a == map->second.active_analog.end()) return 0; int count = 0; - for (auto a: a->second.first) { - switch (a) { + for (auto b: a->second.first) { + switch (b) { case TRIGGER_LEFT: originsOut[count] = k_EInputActionOrigin_XBox360_LeftTrigger_Pull; break; From 71e265f52b455a9a7ab691ba59a9e4cc3ad1abc4 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Mon, 13 Jan 2020 13:47:14 -0500 Subject: [PATCH 03/10] Add env variable to set app path. --- dll/base.cpp | 9 +++++++++ scripts/steamclient_loader.sh | 8 +------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dll/base.cpp b/dll/base.cpp index 5fb65f6..c9e5903 100644 --- a/dll/base.cpp +++ b/dll/base.cpp @@ -193,6 +193,15 @@ std::string get_lib_path() { std::string get_full_program_path() { + std::string env_program_path = get_env_variable("SteamAppPath"); + if (env_program_path.length()) { + if (env_program_path.back() != PATH_SEPARATOR[0]) { + env_program_path = env_program_path.append(PATH_SEPARATOR); + } + + return env_program_path; + } + std::string program_path; #if defined(STEAM_WIN32) char DllPath[MAX_PATH] = {0}; diff --git a/scripts/steamclient_loader.sh b/scripts/steamclient_loader.sh index 0c10d5d..cde258b 100755 --- a/scripts/steamclient_loader.sh +++ b/scripts/steamclient_loader.sh @@ -8,8 +8,6 @@ CUR_DIR=$(pwd) cd "$CONFIG_PATH" mkdir -p ~/.steam/sdk64 mkdir -p ~/.steam/sdk32 -rm -rf ~/.steam/sdk64/steam_settings -rm -rf ~/.steam/sdk32/steam_settings #make a backup of original files mv ~/.steam/steam.pid ~/.steam/steam.pid.orig || true mv ~/.steam/sdk64/steamclient.so ~/.steam/sdk64/steamclient.so.orig || true @@ -17,18 +15,14 @@ mv ~/.steam/sdk32/steamclient.so ~/.steam/sdk32/steamclient.so.orig || true #copy our files cp x86/steamclient.so ~/.steam/sdk32/steamclient.so cp x86_64/steamclient.so ~/.steam/sdk64/steamclient.so -cp -r steam_settings ~/.steam/sdk32/ -cp -r steam_settings ~/.steam/sdk64/ echo $BASHPID > ~/.steam/steam.pid cd "$APP_PATH" -SteamAppId=$APP_ID SteamGameId=$APP_ID "$APP_NAME" +SteamAppPath="$APP_PATH" SteamAppId=$APP_ID SteamGameId=$APP_ID "$APP_NAME" cd "$CUR_DIR" #restore original rm -f ~/.steam/steam.pid rm -f ~/.steam/sdk64/steamclient.so rm -f ~/.steam/sdk32/steamclient.so -rm -rf ~/.steam/sdk64/steam_settings -rm -rf ~/.steam/sdk32/steam_settings mv ~/.steam/steam.pid.orig ~/.steam/steam.pid mv ~/.steam/sdk64/steamclient.so.orig ~/.steam/sdk64/steamclient.so || true mv ~/.steam/sdk32/steamclient.so.orig ~/.steam/sdk32/steamclient.so || true From 4e6aa809de4fcad3c5e239da8c443003366f7788 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Mon, 13 Jan 2020 13:47:47 -0500 Subject: [PATCH 04/10] Kill background thread on client shutdown. --- dll/steam_client.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index a06834a..6a9725a 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -18,16 +18,21 @@ #include "steam_client.h" #include "settings_parser.h" - +static bool kill_background_thread; static void background_thread(Steam_Client *client) { PRINT_DEBUG("background thread starting\n"); while (1) { std::this_thread::sleep_for(std::chrono::seconds(1)); global_mutex.lock(); - if (!client->network->isAlive()) { + bool net_alive = client->network->isAlive(); + if (!net_alive || kill_background_thread) { global_mutex.unlock(); - //delete network; + if (!net_alive) { + //delete network; + } + + kill_background_thread = false; PRINT_DEBUG("background thread exit\n"); return; } @@ -701,6 +706,7 @@ void Steam_Client::SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction bool Steam_Client::BShutdownIfAllPipesClosed() { PRINT_DEBUG("BShutdownIfAllPipesClosed\n"); + kill_background_thread = true; return true; } From 11cb3ce998dfac61df9a8bb5099b075a979b4762 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 10:11:37 -0500 Subject: [PATCH 05/10] Fix some major issues (networking didn't work, gameservers didn't work) with the steamclient version. Implemented a basic steampipe alloc system and fixed build. --- dll/defines.h | 3 - dll/dll.cpp | 69 ++++++++++++++------ dll/steam_client.cpp | 110 +++++++++++++++++++------------- dll/steam_client.h | 10 +++ dll/steam_gameserver.cpp | 5 +- scripts/steamclient_loader.sh | 8 +++ sdk_includes/steam_api_common.h | 8 +++ 7 files changed, 147 insertions(+), 66 deletions(-) diff --git a/dll/defines.h b/dll/defines.h index 73d5995..dbad7dc 100644 --- a/dll/defines.h +++ b/dll/defines.h @@ -2,9 +2,6 @@ #define CLIENT_HSTEAMUSER 12 #define SERVER_HSTEAMUSER 13 -#define CLIENT_STEAM_PIPE 5 -#define SERVER_STEAM_PIPE 6 - #define DEFAULT_NAME "Goldberg" #define PROGRAM_NAME "Goldberg SteamEmu" #define DEFAULT_LANGUAGE "english" diff --git a/dll/dll.cpp b/dll/dll.cpp index 733055e..b027a70 100644 --- a/dll/dll.cpp +++ b/dll/dll.cpp @@ -15,6 +15,7 @@ License along with the Goldberg Emulator; if not, see . */ +#define STEAM_API_FUNCTIONS_IMPL #include "dll.h" @@ -203,14 +204,17 @@ STEAMAPI_API void * S_CALLTYPE SteamInternal_ContextInit( void *pContextInitData //steam_api.h // SteamAPI_Init must be called before using any other API functions. If it fails, an // error message will be output to the debugger (or stderr) with further information. +static HSteamPipe user_steam_pipe; STEAMAPI_API bool S_CALLTYPE SteamAPI_Init() { PRINT_DEBUG("SteamAPI_Init called\n"); + if (user_steam_pipe) return true; #ifdef EMU_EXPERIMENTAL_BUILD crack_SteamAPI_Init(); #endif load_old_interface_versions(); - get_steam_client()->userLogIn(); + user_steam_pipe = get_steam_client()->CreateSteamPipe(); + get_steam_client()->ConnectToGlobalUser(user_steam_pipe); return true; } @@ -226,6 +230,8 @@ STEAMAPI_API void S_CALLTYPE SteamAPI_Shutdown() { PRINT_DEBUG("SteamAPI_Shutdown\n"); get_steam_client()->clientShutdown(); + get_steam_client()->BReleaseSteamPipe(user_steam_pipe); + user_steam_pipe = 0; } // SteamAPI_RestartAppIfNecessary ensures that your executable was launched through Steam. @@ -416,8 +422,7 @@ STEAMAPI_API const char *SteamAPI_GetSteamInstallPath() STEAMAPI_API HSteamPipe SteamAPI_GetHSteamPipe() { PRINT_DEBUG("SteamAPI_GetHSteamPipe\n"); - if (!get_steam_client()->user_logged_in) return 0; - return CLIENT_STEAM_PIPE; + return user_steam_pipe; } // sets whether or not Steam_RunCallbacks() should do a try {} catch (...) {} around calls to issuing callbacks @@ -484,11 +489,11 @@ STEAMAPI_API void * S_CALLTYPE SteamGameServerInternal_CreateInterface( const ch return SteamInternal_CreateInterface(ver); } +static HSteamPipe server_steam_pipe; STEAMAPI_API HSteamPipe S_CALLTYPE SteamGameServer_GetHSteamPipe() { PRINT_DEBUG("SteamGameServer_GetHSteamPipe\n"); - if (!get_steam_client()->server_init) return 0; - return SERVER_STEAM_PIPE; + return server_steam_pipe; } STEAMAPI_API HSteamUser S_CALLTYPE SteamGameServer_GetHSteamUser() @@ -533,10 +538,12 @@ STEAMAPI_API bool S_CALLTYPE SteamInternal_GameServer_Init( uint32 unIP, uint16 { PRINT_DEBUG("SteamInternal_GameServer_Init %u %hu %hu %hu %u %s\n", unIP, usPort, usGamePort, usQueryPort, eServerMode, pchVersionString); load_old_interface_versions(); - get_steam_client()->serverInit(); + get_steam_client()->CreateLocalUser(&server_steam_pipe, k_EAccountTypeGameServer); //g_pSteamClientGameServer is only used in pre 1.37 (where the interface versions are not provided by the game) g_pSteamClientGameServer = SteamGameServerClient(); - return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, eServerMode, 0, pchVersionString); + uint32 unFlags = 0; + if (eServerMode == eServerModeAuthenticationAndSecure) unFlags = k_unServerFlagSecure; + return get_steam_client()->steam_gameserver->InitGameServer(unIP, usGamePort, usQueryPort, unFlags, 0, pchVersionString); } //SteamGameServer004 and before: @@ -575,7 +582,9 @@ STEAMAPI_API bool SteamGameServer_Init( uint32 unIP, uint16 usSteamPort, uint16 STEAMAPI_API void SteamGameServer_Shutdown() { PRINT_DEBUG("SteamGameServer_Shutdown\n"); - get_steam_clientserver_old()->serverShutdown(); + get_steam_client()->serverShutdown(); + get_steam_client()->BReleaseSteamPipe(server_steam_pipe); + server_steam_pipe = 0; g_pSteamClientGameServer = NULL; //TODO: check if this actually gets nulled when SteamGameServer_Shutdown is called } @@ -752,15 +761,26 @@ STEAMCLIENT_API bool Steam_BGetCallback( HSteamPipe hSteamPipe, CallbackMsg_t *p PRINT_DEBUG("%s %i\n", __FUNCTION__, hSteamPipe); std::queue *q = NULL; HSteamUser m_hSteamUser = 0; - get_steam_client()->callback_results_server->setCbAll(&cb_add_queue_server); - get_steam_client()->callback_results_client->setCbAll(&cb_add_queue_client); - get_steam_client()->RunCallbacks(true, true); - if (hSteamPipe == SERVER_STEAM_PIPE) { + Steam_Client *steam_client = get_steam_client(); + steam_client->callback_results_server->setCbAll(&cb_add_queue_server); + steam_client->callback_results_client->setCbAll(&cb_add_queue_client); + steam_client->RunCallbacks(true, true); + if (!steam_client->steamclient_server_inited) { + while(!server_cb.empty()) server_cb.pop(); + } + + if (!steam_client->steam_pipes.count(hSteamPipe)) { + return false; + } + + if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) { q = &server_cb; m_hSteamUser = SERVER_HSTEAMUSER; - } else { + } else if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::CLIENT) { q = &client_cb; m_hSteamUser = CLIENT_HSTEAMUSER; + } else { + return false; } if (q->empty()) return false; @@ -780,10 +800,17 @@ STEAMCLIENT_API void Steam_FreeLastCallback( HSteamPipe hSteamPipe ) { PRINT_DEBUG("%s %i\n", __FUNCTION__, hSteamPipe); std::queue *q = NULL; - if (hSteamPipe == SERVER_STEAM_PIPE) { + Steam_Client *steam_client = get_steam_client(); + if (!steam_client->steam_pipes.count(hSteamPipe)) { + return; + } + + if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) { q = &server_cb; - } else { + } else if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::CLIENT) { q = &client_cb; + } else { + return; } if (!q->empty()) q->pop(); @@ -792,11 +819,17 @@ STEAMCLIENT_API void Steam_FreeLastCallback( HSteamPipe hSteamPipe ) STEAMCLIENT_API bool Steam_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void* pCallback, int cubCallback, int iCallbackExpected, bool* pbFailed ) { PRINT_DEBUG("Steam_GetAPICallResult %i %llu %i %i\n", hSteamPipe, hSteamAPICall, cubCallback, iCallbackExpected); - if (!hSteamPipe) return false; - if (hSteamPipe == SERVER_STEAM_PIPE) { + Steam_Client *steam_client = get_steam_client(); + if (!steam_client->steam_pipes.count(hSteamPipe)) { + return false; + } + + if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) { return get_steam_client()->steam_gameserver_utils->GetAPICallResult(hSteamAPICall, pCallback, cubCallback, iCallbackExpected, pbFailed); - } else { + } else if (steam_client->steam_pipes[hSteamPipe] == Steam_Pipe::CLIENT) { return get_steam_client()->steam_utils->GetAPICallResult(hSteamAPICall, pCallback, cubCallback, iCallbackExpected, pbFailed); + } else { + return false; } } diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index 6a9725a..d997454 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -159,15 +159,24 @@ void Steam_Client::setAppID(uint32 appid) HSteamPipe Steam_Client::CreateSteamPipe() { PRINT_DEBUG("CreateSteamPipe\n"); - return CLIENT_STEAM_PIPE; + HSteamPipe pipe = steam_pipe_counter++; + PRINT_DEBUG("creating pipe %i\n", pipe); + + steam_pipes[pipe] = Steam_Pipe::NO_USER; + return pipe; } // Releases a previously created communications pipe // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling bool Steam_Client::BReleaseSteamPipe( HSteamPipe hSteamPipe ) { - PRINT_DEBUG("BReleaseSteamPipe\n"); - return true; + PRINT_DEBUG("BReleaseSteamPipe %i\n", hSteamPipe); + if (steam_pipes.count(hSteamPipe)) { + steam_pipes.erase(hSteamPipe); + return true; + } + + return false; } // connects to an existing global user, failing if none exists @@ -175,7 +184,13 @@ bool Steam_Client::BReleaseSteamPipe( HSteamPipe hSteamPipe ) // NOT THREADSAFE - ensure that no other threads are accessing Steamworks API when calling HSteamUser Steam_Client::ConnectToGlobalUser( HSteamPipe hSteamPipe ) { - PRINT_DEBUG("ConnectToGlobalUser\n"); + PRINT_DEBUG("ConnectToGlobalUser %i\n", hSteamPipe); + if (!steam_pipes.count(hSteamPipe)) { + return 0; + } + + userLogIn(); + steam_pipes[hSteamPipe] = Steam_Pipe::CLIENT; return CLIENT_HSTEAMUSER; } @@ -184,13 +199,19 @@ HSteamUser Steam_Client::ConnectToGlobalUser( HSteamPipe hSteamPipe ) HSteamUser Steam_Client::CreateLocalUser( HSteamPipe *phSteamPipe, EAccountType eAccountType ) { PRINT_DEBUG("CreateLocalUser %p %i\n", phSteamPipe, eAccountType); - if (eAccountType == k_EAccountTypeIndividual) { - if (phSteamPipe) *phSteamPipe = CLIENT_STEAM_PIPE; - return CLIENT_HSTEAMUSER; - } else { - if (phSteamPipe) *phSteamPipe = SERVER_STEAM_PIPE; - return SERVER_HSTEAMUSER; - } + //if (eAccountType == k_EAccountTypeIndividual) { + //Is this actually used? + //if (phSteamPipe) *phSteamPipe = CLIENT_STEAM_PIPE; + //return CLIENT_HSTEAMUSER; + //} else { //k_EAccountTypeGameServer + serverInit(); + + HSteamPipe pipe = CreateSteamPipe(); + if (phSteamPipe) *phSteamPipe = pipe; + steam_pipes[pipe] = Steam_Pipe::SERVER; + steamclient_server_inited = true; + return SERVER_HSTEAMUSER; + //} } HSteamUser Steam_Client::CreateLocalUser( HSteamPipe *phSteamPipe ) @@ -203,13 +224,16 @@ HSteamUser Steam_Client::CreateLocalUser( HSteamPipe *phSteamPipe ) void Steam_Client::ReleaseUser( HSteamPipe hSteamPipe, HSteamUser hUser ) { PRINT_DEBUG("ReleaseUser\n"); + if (hUser == SERVER_HSTEAMUSER && steam_pipes.count(hSteamPipe)) { + steamclient_server_inited = false; + } } // retrieves the ISteamUser interface associated with the handle ISteamUser *Steam_Client::GetISteamUser( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamUser %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "SteamUser009") == 0) { return (ISteamUser *)(void *)(ISteamUser009 *)steam_user; @@ -246,7 +270,7 @@ ISteamUser *Steam_Client::GetISteamUser( HSteamUser hSteamUser, HSteamPipe hStea ISteamGameServer *Steam_Client::GetISteamGameServer( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamGameServer %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "SteamGameServer005") == 0) { return (ISteamGameServer *)(void *)(ISteamGameServer005 *)steam_gameserver; @@ -289,7 +313,7 @@ void Steam_Client::SetLocalIPBinding( const SteamIPAddress_t &unIP, uint16 usPor ISteamFriends *Steam_Client::GetISteamFriends( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamFriends %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "SteamFriends004") == 0) { return (ISteamFriends *)(void *)(ISteamFriends004 *)steam_friends; @@ -330,11 +354,11 @@ ISteamFriends *Steam_Client::GetISteamFriends( HSteamUser hSteamUser, HSteamPipe ISteamUtils *Steam_Client::GetISteamUtils( HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamUtils %s\n", pchVersion); - if (!hSteamPipe) return NULL; + if (!steam_pipes.count(hSteamPipe)) return NULL; Steam_Utils *steam_utils_temp; - if (hSteamPipe == SERVER_STEAM_PIPE) { + if (steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) { steam_utils_temp = steam_gameserver_utils; } else { steam_utils_temp = steam_utils; @@ -367,7 +391,7 @@ ISteamUtils *Steam_Client::GetISteamUtils( HSteamPipe hSteamPipe, const char *pc ISteamMatchmaking *Steam_Client::GetISteamMatchmaking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamMatchmaking %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "SteamMatchMaking001") == 0) { //TODO @@ -404,7 +428,7 @@ ISteamMatchmaking *Steam_Client::GetISteamMatchmaking( HSteamUser hSteamUser, HS ISteamMatchmakingServers *Steam_Client::GetISteamMatchmakingServers( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamMatchmakingServers %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_matchmaking_servers; } @@ -412,7 +436,7 @@ ISteamMatchmakingServers *Steam_Client::GetISteamMatchmakingServers( HSteamUser void *Steam_Client::GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamGenericInterface %s\n", pchVersion); - if (!hSteamPipe) return NULL; + if (!steam_pipes.count(hSteamPipe)) return NULL; bool server = false; if (hSteamUser == SERVER_HSTEAMUSER) { @@ -541,7 +565,7 @@ void *Steam_Client::GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe ISteamUserStats *Steam_Client::GetISteamUserStats( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamUserStats %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "STEAMUSERSTATS_INTERFACE_VERSION001") == 0) { //TODO @@ -578,7 +602,7 @@ ISteamUserStats *Steam_Client::GetISteamUserStats( HSteamUser hSteamUser, HSteam ISteamGameServerStats *Steam_Client::GetISteamGameServerStats( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamGameServerStats %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_gameserverstats; } @@ -586,7 +610,7 @@ ISteamGameServerStats *Steam_Client::GetISteamGameServerStats( HSteamUser hSteam ISteamApps *Steam_Client::GetISteamApps( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamApps %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (hSteamUser == SERVER_HSTEAMUSER) { return steam_gameserver_apps; } @@ -598,7 +622,7 @@ ISteamApps *Steam_Client::GetISteamApps( HSteamUser hSteamUser, HSteamPipe hStea ISteamNetworking *Steam_Client::GetISteamNetworking( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamNetworking %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; Steam_Networking *steam_networking_temp; @@ -631,7 +655,7 @@ ISteamNetworking *Steam_Client::GetISteamNetworking( HSteamUser hSteamUser, HSte ISteamRemoteStorage *Steam_Client::GetISteamRemoteStorage( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamRemoteStorage %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; if (strcmp(pchVersion, "STEAMREMOTESTORAGE_INTERFACE_VERSION001") == 0) { return (ISteamRemoteStorage *)(void *)(ISteamRemoteStorage001 *)steam_remote_storage; @@ -672,7 +696,7 @@ ISteamRemoteStorage *Steam_Client::GetISteamRemoteStorage( HSteamUser hSteamuser ISteamScreenshots *Steam_Client::GetISteamScreenshots( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamScreenshots %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_screenshots; } @@ -714,7 +738,7 @@ bool Steam_Client::BShutdownIfAllPipesClosed() ISteamHTTP *Steam_Client::GetISteamHTTP( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamHTTP %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; if (hSteamuser == SERVER_HSTEAMUSER) { return steam_gameserver_http; } @@ -726,14 +750,14 @@ ISteamHTTP *Steam_Client::GetISteamHTTP( HSteamUser hSteamuser, HSteamPipe hStea void *Steam_Client::DEPRECATED_GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("DEPRECATED_GetISteamUnifiedMessages %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return (void *)(ISteamUnifiedMessages *)steam_unified_messages; } ISteamUnifiedMessages *Steam_Client::GetISteamUnifiedMessages( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamUnifiedMessages %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_unified_messages; } @@ -741,7 +765,7 @@ ISteamUnifiedMessages *Steam_Client::GetISteamUnifiedMessages( HSteamUser hSteam ISteamController *Steam_Client::GetISteamController( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamController %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; if (strcmp(pchVersion, "STEAMCONTROLLER_INTERFACE_VERSION") == 0) { return (ISteamController *)(void *)(ISteamController001 *)steam_controller; @@ -769,7 +793,7 @@ ISteamController *Steam_Client::GetISteamController( HSteamUser hSteamUser, HSte ISteamUGC *Steam_Client::GetISteamUGC( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamUGC %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; Steam_UGC *steam_ugc_temp; if (hSteamUser == SERVER_HSTEAMUSER) { @@ -821,7 +845,7 @@ ISteamUGC *Steam_Client::GetISteamUGC( HSteamUser hSteamUser, HSteamPipe hSteamP ISteamAppList *Steam_Client::GetISteamAppList( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamAppList %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_applist; } @@ -829,7 +853,7 @@ ISteamAppList *Steam_Client::GetISteamAppList( HSteamUser hSteamUser, HSteamPipe ISteamMusic *Steam_Client::GetISteamMusic( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamMusic %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_music; } @@ -837,7 +861,7 @@ ISteamMusic *Steam_Client::GetISteamMusic( HSteamUser hSteamuser, HSteamPipe hSt ISteamMusicRemote *Steam_Client::GetISteamMusicRemote(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) { PRINT_DEBUG("GetISteamMusicRemote %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_musicremote; } @@ -845,7 +869,7 @@ ISteamMusicRemote *Steam_Client::GetISteamMusicRemote(HSteamUser hSteamuser, HSt ISteamHTMLSurface *Steam_Client::GetISteamHTMLSurface(HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion) { PRINT_DEBUG("GetISteamHTMLSurface %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; if (strcmp(pchVersion, "STEAMHTMLSURFACE_INTERFACE_VERSION_001") == 0) { return (ISteamHTMLSurface *)(void *)(ISteamHTMLSurface001 *)steam_HTMLsurface; @@ -894,7 +918,7 @@ void Steam_Client::Remove_SteamAPI_CPostAPIResultInProcess( SteamAPI_PostAPIResu ISteamInventory *Steam_Client::GetISteamInventory( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamInventory %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; Steam_Inventory *steam_inventory_temp; Settings *settings_temp; SteamCallBacks *callbacks_temp; @@ -923,7 +947,7 @@ ISteamInventory *Steam_Client::GetISteamInventory( HSteamUser hSteamuser, HSteam ISteamVideo *Steam_Client::GetISteamVideo( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamVideo %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_video; } @@ -931,21 +955,21 @@ ISteamVideo *Steam_Client::GetISteamVideo( HSteamUser hSteamuser, HSteamPipe hSt ISteamParentalSettings *Steam_Client::GetISteamParentalSettings( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamParentalSettings %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_parental; } ISteamMasterServerUpdater *Steam_Client::GetISteamMasterServerUpdater( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamMasterServerUpdater %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_masterserver_updater; } ISteamContentServer *Steam_Client::GetISteamContentServer( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamContentServer %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return NULL; } @@ -953,7 +977,7 @@ ISteamContentServer *Steam_Client::GetISteamContentServer( HSteamUser hSteamUser ISteamGameSearch *Steam_Client::GetISteamGameSearch( HSteamUser hSteamuser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamGameSearch %s\n", pchVersion); - if (!hSteamPipe || !hSteamuser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamuser) return NULL; return steam_game_search; } @@ -962,7 +986,7 @@ ISteamGameSearch *Steam_Client::GetISteamGameSearch( HSteamUser hSteamuser, HSte ISteamInput *Steam_Client::GetISteamInput( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamInput %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_controller; } @@ -971,7 +995,7 @@ ISteamInput *Steam_Client::GetISteamInput( HSteamUser hSteamUser, HSteamPipe hSt ISteamParties *Steam_Client::GetISteamParties( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamParties %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_parties; } @@ -979,7 +1003,7 @@ ISteamParties *Steam_Client::GetISteamParties( HSteamUser hSteamUser, HSteamPipe ISteamRemotePlay *Steam_Client::GetISteamRemotePlay( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion ) { PRINT_DEBUG("GetISteamRemotePlay %s\n", pchVersion); - if (!hSteamPipe || !hSteamUser) return NULL; + if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return NULL; return steam_remoteplay; } diff --git a/dll/steam_client.h b/dll/steam_client.h index 73b93af..753e397 100644 --- a/dll/steam_client.h +++ b/dll/steam_client.h @@ -55,6 +55,12 @@ #include +enum Steam_Pipe { + NO_USER, + CLIENT, + SERVER +}; + class Steam_Client : public ISteamClient007, public ISteamClient008, @@ -124,6 +130,10 @@ public: bool user_logged_in = false; bool server_init = false; std::thread background_keepalive; + bool steamclient_server_inited = false; + + unsigned steam_pipe_counter = 2; + std::map steam_pipes; Steam_Client(); ~Steam_Client(); diff --git a/dll/steam_gameserver.cpp b/dll/steam_gameserver.cpp index c2d6625..6735456 100644 --- a/dll/steam_gameserver.cpp +++ b/dll/steam_gameserver.cpp @@ -177,7 +177,7 @@ bool Steam_GameServer::BSecure() PRINT_DEBUG("BSecure\n"); std::lock_guard lock(global_mutex); if (!policy_response_called) return false; - return flags == eServerModeAuthenticationAndSecure; + return !!(flags & k_unServerFlagSecure); } CSteamID Steam_GameServer::GetSteamID() @@ -414,6 +414,7 @@ bool Steam_GameServer::BSetServerType( uint32 unServerFlags, uint32 unGameIP, ui version.erase(std::remove(version.begin(), version.end(), ' '), version.end()); version.erase(std::remove(version.begin(), version.end(), '.'), version.end()); server_data.set_version(stoi(version)); + flags = unServerFlags; //TODO? return true; @@ -662,7 +663,7 @@ void Steam_GameServer::RunCallbacks() if (logged_in && !policy_response_called) { PRINT_DEBUG("Steam_GameServer::GSPolicyResponse_t\n"); GSPolicyResponse_t data; - data.m_bSecure = flags == eServerModeAuthenticationAndSecure; + data.m_bSecure = !!(flags & k_unServerFlagSecure); callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), 0.11); policy_response_called = true; } diff --git a/scripts/steamclient_loader.sh b/scripts/steamclient_loader.sh index cde258b..53074e4 100755 --- a/scripts/steamclient_loader.sh +++ b/scripts/steamclient_loader.sh @@ -3,6 +3,8 @@ APP_NAME="bin/test_executable" APP_ID=480 APP_PATH=$(dirname "$0") CONFIG_PATH=$(dirname "$0") +#path to steam-runtime/run.sh +STEAM_RUNTIME="" CUR_DIR=$(pwd) cd "$CONFIG_PATH" @@ -17,7 +19,13 @@ cp x86/steamclient.so ~/.steam/sdk32/steamclient.so cp x86_64/steamclient.so ~/.steam/sdk64/steamclient.so echo $BASHPID > ~/.steam/steam.pid cd "$APP_PATH" +if [ -z "$STEAM_RUNTIME" ] +then SteamAppPath="$APP_PATH" SteamAppId=$APP_ID SteamGameId=$APP_ID "$APP_NAME" +else +SteamAppPath="$APP_PATH" SteamAppId=$APP_ID SteamGameId=$APP_ID "$STEAM_RUNTIME" "$APP_NAME" +fi + cd "$CUR_DIR" #restore original rm -f ~/.steam/steam.pid diff --git a/sdk_includes/steam_api_common.h b/sdk_includes/steam_api_common.h index 44c8291..73c6a6e 100644 --- a/sdk_includes/steam_api_common.h +++ b/sdk_includes/steam_api_common.h @@ -39,11 +39,19 @@ #endif // STEAM_API_EXPORTS #endif +#ifdef STEAM_API_EXPORTS +#ifdef STEAM_API_FUNCTIONS_IMPL #ifdef STEAMCLIENT_DLL #define S_API static #else #define S_API S_API_EXPORT #endif +#else +#define S_API +#endif +#else +#define S_API S_API_EXPORT +#endif #if ( defined(STEAM_API_EXPORTS) || defined(STEAM_API_NODLL) ) && !defined(API_GEN) #define STEAM_PRIVATE_API( ... ) __VA_ARGS__ From 81830efd58333e52acbc511eefc1a2f4e2484264 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 12:40:18 -0500 Subject: [PATCH 06/10] Close background thread on steamclient shutdown. --- dll/steam_client.cpp | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/dll/steam_client.cpp b/dll/steam_client.cpp index d997454..a81259e 100644 --- a/dll/steam_client.cpp +++ b/dll/steam_client.cpp @@ -18,25 +18,25 @@ #include "steam_client.h" #include "settings_parser.h" -static bool kill_background_thread; +#include + +static std::condition_variable kill_background_thread_cv; +static std::atomic_bool kill_background_thread; static void background_thread(Steam_Client *client) { PRINT_DEBUG("background thread starting\n"); - while (1) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - global_mutex.lock(); - bool net_alive = client->network->isAlive(); - if (!net_alive || kill_background_thread) { - global_mutex.unlock(); - if (!net_alive) { - //delete network; - } + std::mutex mtx; + std::unique_lock lck(mtx); - kill_background_thread = false; - PRINT_DEBUG("background thread exit\n"); - return; + while (1) { + if (kill_background_thread || kill_background_thread_cv.wait_for(lck, std::chrono::seconds(1)) != std::cv_status::timeout) { + if (kill_background_thread) { + PRINT_DEBUG("background thread exit\n"); + return; + } } + global_mutex.lock(); PRINT_DEBUG("background thread run\n"); client->network->Run(); client->steam_matchmaking->RunBackground(); @@ -730,8 +730,18 @@ void Steam_Client::SetWarningMessageHook( SteamAPIWarningMessageHook_t pFunction bool Steam_Client::BShutdownIfAllPipesClosed() { PRINT_DEBUG("BShutdownIfAllPipesClosed\n"); - kill_background_thread = true; - return true; + if (!steam_pipes.size()) { + if (background_keepalive.joinable()) { + kill_background_thread = true; + kill_background_thread_cv.notify_one(); + background_keepalive.join(); + } + + PRINT_DEBUG("all pipes closed\n"); + return true; + } + + return false; } // Expose HTTP interface From 0ed433cb26981019169b73c5bf461ed0e2caaf90 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 13:18:12 -0500 Subject: [PATCH 07/10] Add a bundle of the source code to the git builds zip. --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 70847c5..e466878 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -153,6 +153,9 @@ deploy_all: script: - ls -lah + - mkdir -p release/source_code + - git bundle create release/source_code/source_code.bundle --all + - echo 'This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master' > release/source_code/Readme.txt - mv linux release/ - shopt -s extglob - rm -rf .g* From 47c8f0a2a11c134b0f0d41e9b44ebf99f9e259db Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 13:21:37 -0500 Subject: [PATCH 08/10] Fix yaml? --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e466878..2133b63 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -155,7 +155,7 @@ deploy_all: - ls -lah - mkdir -p release/source_code - git bundle create release/source_code/source_code.bundle --all - - echo 'This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master' > release/source_code/Readme.txt + - echo "This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master" > release/source_code/Readme.txt - mv linux release/ - shopt -s extglob - rm -rf .g* From d9173e7b502e2ccf8d241908bf368738e142143a Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 13:27:15 -0500 Subject: [PATCH 09/10] Fix yaml. --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2133b63..78e7d9d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -155,7 +155,7 @@ deploy_all: - ls -lah - mkdir -p release/source_code - git bundle create release/source_code/source_code.bundle --all - - echo "This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master" > release/source_code/Readme.txt + - "echo \"This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master\" > release/source_code/Readme.txt" - mv linux release/ - shopt -s extglob - rm -rf .g* From 0c4831260e0af07a0303b4ad16f5596ca7f49240 Mon Sep 17 00:00:00 2001 From: Mr_Goldberg Date: Wed, 15 Jan 2020 14:27:27 -0500 Subject: [PATCH 10/10] Forgot this. --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 78e7d9d..f307d10 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -153,6 +153,7 @@ deploy_all: script: - ls -lah + - dnf -y install git - mkdir -p release/source_code - git bundle create release/source_code/source_code.bundle --all - "echo \"This is a git bundle of the full repo, to use: git clone source_code.bundle --branch master\" > release/source_code/Readme.txt"