mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-05 01:38:12 -07:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 08e99dea4a | |||
| 00e904539e | |||
| eaab4698eb | |||
| a48eccab93 | |||
| 81c913726d |
+1
-1
@@ -105,5 +105,5 @@ if (conditional)
|
|||||||
* We don't use GSL.
|
* We don't use GSL.
|
||||||
* Don't throw exceptions.
|
* Don't throw exceptions.
|
||||||
* Stick to smart pointers. For interfacing with C Win32 API and raw buffers, use `unique_plain_ptr`.
|
* Stick to smart pointers. For interfacing with C Win32 API and raw buffers, use `unique_plain_ptr`.
|
||||||
* Writing in C is also completely acceptable.
|
* Writing in C is also completely acceptable but prefer to use RAII patterns.
|
||||||
* Other than that, there are no strict rules for code formatting, but please attempt to emulate the style around the code you are modifying.
|
* Other than that, there are no strict rules for code formatting, but please attempt to emulate the style around the code you are modifying.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "cfg/configurator.h"
|
#include "cfg/configurator.h"
|
||||||
#include "external/rapidjson/document.h"
|
#include "external/rapidjson/document.h"
|
||||||
|
#include "external/rapidjson/error/en.h"
|
||||||
#include "util/crypt.h"
|
#include "util/crypt.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "util/utils.h"
|
#include "util/utils.h"
|
||||||
@@ -92,6 +93,7 @@ Controller::Controller(unsigned short port, std::string password, bool pretty)
|
|||||||
// bind socket to address
|
// bind socket to address
|
||||||
if (bind(this->server, (sockaddr *) &server_address, sizeof(sockaddr)) == -1) {
|
if (bind(this->server, (sockaddr *) &server_address, sizeof(sockaddr)) == -1) {
|
||||||
log_warning("api", "could not bind socket on port {}: {}", port, get_last_error_string());
|
log_warning("api", "could not bind socket on port {}: {}", port, get_last_error_string());
|
||||||
|
closesocket(this->server);
|
||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
if (!cfg::CONFIGURATOR_STANDALONE) {
|
if (!cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_fatal("api", "failed to start server");
|
log_fatal("api", "failed to start server");
|
||||||
@@ -102,6 +104,7 @@ Controller::Controller(unsigned short port, std::string password, bool pretty)
|
|||||||
// set socket to listen
|
// set socket to listen
|
||||||
if (listen(this->server, server_backlog) == -1) {
|
if (listen(this->server, server_backlog) == -1) {
|
||||||
log_warning("api", "could not listen to socket on port {}: {}", port, get_last_error_string());
|
log_warning("api", "could not listen to socket on port {}: {}", port, get_last_error_string());
|
||||||
|
closesocket(this->server);
|
||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
if (!cfg::CONFIGURATOR_STANDALONE) {
|
if (!cfg::CONFIGURATOR_STANDALONE) {
|
||||||
log_fatal("api", "failed to start server");
|
log_fatal("api", "failed to start server");
|
||||||
@@ -312,6 +315,8 @@ bool Controller::process_request(ClientState *state, const char *in, size_t in_s
|
|||||||
|
|
||||||
// check for parse error
|
// check for parse error
|
||||||
if (document.HasParseError()) {
|
if (document.HasParseError()) {
|
||||||
|
log_warning("api", "Request JSON parse error: {} (byte offset {}, decrypted request length {} bytes)",
|
||||||
|
GetParseError_En(document.GetParseError()), document.GetErrorOffset(), in_size);
|
||||||
|
|
||||||
// return empty response and close connection
|
// return empty response and close connection
|
||||||
out->push_back(0);
|
out->push_back(0);
|
||||||
@@ -443,7 +448,9 @@ void Controller::free_socket() {
|
|||||||
this->server = INVALID_SOCKET;
|
this->server = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->websocket->free_socket();
|
if (this->websocket) {
|
||||||
|
this->websocket->free_socket();
|
||||||
|
}
|
||||||
|
|
||||||
for (auto &s : this->serial) {
|
for (auto &s : this->serial) {
|
||||||
s->free_port();
|
s->free_port();
|
||||||
|
|||||||
@@ -41,21 +41,21 @@ namespace api {
|
|||||||
bool pretty;
|
bool pretty;
|
||||||
|
|
||||||
// server
|
// server
|
||||||
WebSocketController *websocket;
|
WebSocketController *websocket = nullptr;
|
||||||
std::vector<SerialController *> serial;
|
std::vector<SerialController *> serial;
|
||||||
std::vector<std::thread> server_workers;
|
std::vector<std::thread> server_workers;
|
||||||
std::vector<std::thread> server_handlers;
|
std::vector<std::thread> server_handlers;
|
||||||
std::mutex server_handlers_m;
|
std::mutex server_handlers_m;
|
||||||
std::vector<api::ClientState *> client_states;
|
std::vector<api::ClientState *> client_states;
|
||||||
std::mutex client_states_m;
|
std::mutex client_states_m;
|
||||||
SOCKET server;
|
SOCKET server = INVALID_SOCKET;
|
||||||
void server_worker();
|
void server_worker();
|
||||||
void connection_handler(ClientState client_state);
|
void connection_handler(ClientState client_state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// state
|
// state
|
||||||
bool server_running;
|
bool server_running = false;
|
||||||
|
|
||||||
// constructor / destructor
|
// constructor / destructor
|
||||||
Controller(unsigned short port, std::string password, bool pretty);
|
Controller(unsigned short port, std::string password, bool pretty);
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace api::modules {
|
|||||||
return error_type(res, "amount", "int");
|
return error_type(res, "amount", "int");
|
||||||
|
|
||||||
// add to coin stock
|
// add to coin stock
|
||||||
eamuse_coin_set_stock(eamuse_coin_get_stock() + std::max(0, req.params[0].GetInt()));
|
eamuse_coin_add(std::max(0, req.params[0].GetInt()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -331,8 +331,8 @@ int eamuse_coin_consume_stock() {
|
|||||||
return COIN_STOCK.exchange(0, std::memory_order_relaxed);
|
return COIN_STOCK.exchange(0, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
int eamuse_coin_add() {
|
void eamuse_coin_add(int amount) {
|
||||||
return COIN_STOCK.fetch_add(1, std::memory_order_relaxed) + 1;
|
COIN_STOCK.fetch_add(amount, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eamuse_coin_insert() {
|
void eamuse_coin_insert() {
|
||||||
@@ -621,6 +621,7 @@ int eamuse_get_game_keypads() {
|
|||||||
avs::game::is_model("JDX") ||
|
avs::game::is_model("JDX") ||
|
||||||
avs::game::is_model("KDX") ||
|
avs::game::is_model("KDX") ||
|
||||||
avs::game::is_model("MDX") ||
|
avs::game::is_model("MDX") ||
|
||||||
|
avs::game::is_model("KDM") ||
|
||||||
avs::game::is_model("J33") ||
|
avs::game::is_model("J33") ||
|
||||||
avs::game::is_model("K33") ||
|
avs::game::is_model("K33") ||
|
||||||
avs::game::is_model("L33") ||
|
avs::game::is_model("L33") ||
|
||||||
@@ -637,6 +638,7 @@ int eamuse_get_game_keypads_name() {
|
|||||||
|
|
||||||
if (game_name == "Beatmania IIDX" ||
|
if (game_name == "Beatmania IIDX" ||
|
||||||
game_name == "Dance Dance Revolution" ||
|
game_name == "Dance Dance Revolution" ||
|
||||||
|
game_name == "Dance Evolution" ||
|
||||||
game_name == "GitaDora")
|
game_name == "GitaDora")
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void eamuse_coin_set_stock(int amount);
|
|||||||
bool eamuse_coin_consume(int amount);
|
bool eamuse_coin_consume(int amount);
|
||||||
int eamuse_coin_consume_stock();
|
int eamuse_coin_consume_stock();
|
||||||
|
|
||||||
int eamuse_coin_add();
|
void eamuse_coin_add(int amount = 1);
|
||||||
void eamuse_coin_insert();
|
void eamuse_coin_insert();
|
||||||
|
|
||||||
void eamuse_pin_macro_start_thread();
|
void eamuse_pin_macro_start_thread();
|
||||||
|
|||||||
@@ -237,6 +237,16 @@ typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_add_toast_func)(
|
|||||||
const char *text
|
const char *text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// insert_coin (v0.3 and up)
|
||||||
|
// adds to the shared coin stock, bypassing the coin blocker like the Spice API
|
||||||
|
//
|
||||||
|
// amount: number of coins to insert (0 to 255); use 1 for a single coin
|
||||||
|
// zero succeeds without changing the stock
|
||||||
|
|
||||||
|
typedef SPICE_SDK_STATUS_CODE (__cdecl spice_sdk_insert_coin_func)(
|
||||||
|
uint8_t amount
|
||||||
|
);
|
||||||
|
|
||||||
typedef struct SPICE_SDK_V0 {
|
typedef struct SPICE_SDK_V0 {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
@@ -262,6 +272,8 @@ typedef struct SPICE_SDK_V0 {
|
|||||||
|
|
||||||
spice_sdk_add_toast_func *add_toast;
|
spice_sdk_add_toast_func *add_toast;
|
||||||
|
|
||||||
|
spice_sdk_insert_coin_func *insert_coin;
|
||||||
|
|
||||||
} SPICE_SDK_V0;
|
} SPICE_SDK_V0;
|
||||||
|
|
||||||
typedef void (__cdecl spice_sdk_destroy_callback_func)(
|
typedef void (__cdecl spice_sdk_destroy_callback_func)(
|
||||||
|
|||||||
@@ -76,9 +76,35 @@ static ArrowButton arrow_buttons[] = {
|
|||||||
|
|
||||||
// worker thread for I/O
|
// worker thread for I/O
|
||||||
static void worker_thread_main(std::stop_token stop_token) {
|
static void worker_thread_main(std::stop_token stop_token) {
|
||||||
|
bool coin_previous_state[10] = {};
|
||||||
while (!stop_token.stop_requested()) {
|
while (!stop_token.stop_requested()) {
|
||||||
|
|
||||||
|
// insert coin
|
||||||
|
const bool control_pressed = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0;
|
||||||
|
for (uint8_t amount = 0; amount < 10; amount++) {
|
||||||
|
const bool coin_pressed = control_pressed &&
|
||||||
|
((GetAsyncKeyState('0' + amount) & 0x8000) != 0);
|
||||||
|
|
||||||
|
if (coin_pressed && !coin_previous_state[amount] && spice.insert_coin) {
|
||||||
|
const auto status = spice.insert_coin(amount);
|
||||||
|
if (status != SPICE_SDK_STATUS_SUCCESS) {
|
||||||
|
LOG_INFO(std::format(
|
||||||
|
"coin insertion failed: {}",
|
||||||
|
static_cast<int>(status)).c_str());
|
||||||
|
} else {
|
||||||
|
const auto message = std::format(
|
||||||
|
"v0_cpp: inserted {} coin{}", amount, amount == 1 ? "" : "s");
|
||||||
|
LOG_INFO(message.c_str());
|
||||||
|
if (spice.add_toast) {
|
||||||
|
spice.add_toast(SPICE_SDK_TOAST_LEVEL_SUCCESS, message.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
coin_previous_state[amount] = coin_pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for ctrl + arrow keys and trigger p1 pad arrows
|
||||||
for (auto& arrow : arrow_buttons) {
|
for (auto& arrow : arrow_buttons) {
|
||||||
// check for ctrl + arrow keys and trigger p1 pad arrows
|
|
||||||
if (((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
|
if (((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
|
||||||
((GetAsyncKeyState(arrow.key) & 0x8000) != 0)) {
|
((GetAsyncKeyState(arrow.key) & 0x8000) != 0)) {
|
||||||
spice.set_button(arrow.button, true, 1.f);
|
spice.set_button(arrow.button, true, 1.f);
|
||||||
@@ -88,7 +114,7 @@ static void worker_thread_main(std::stop_token stop_token) {
|
|||||||
if (spice.add_toast) {
|
if (spice.add_toast) {
|
||||||
spice.add_toast(
|
spice.add_toast(
|
||||||
SPICE_SDK_TOAST_LEVEL_INFO,
|
SPICE_SDK_TOAST_LEVEL_INFO,
|
||||||
std::format("let me hear you say: {}", arrow.name).c_str());
|
std::format("v0_cpp: let me hear you say: {}", arrow.name).c_str());
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO(std::format("let me hear you say: {}", arrow.name).c_str());
|
LOG_INFO(std::format("let me hear you say: {}", arrow.name).c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -31,6 +31,7 @@ static spice_sdk_clear_touch_func sdk_clear_touch;
|
|||||||
static spice_sdk_insert_card_func sdk_insert_card;
|
static spice_sdk_insert_card_func sdk_insert_card;
|
||||||
static spice_sdk_set_keypad_func sdk_set_keypad;
|
static spice_sdk_set_keypad_func sdk_set_keypad;
|
||||||
static spice_sdk_add_toast_func sdk_add_toast;
|
static spice_sdk_add_toast_func sdk_add_toast;
|
||||||
|
static spice_sdk_insert_coin_func sdk_insert_coin;
|
||||||
|
|
||||||
struct SdkModule {
|
struct SdkModule {
|
||||||
std::string dll;
|
std::string dll;
|
||||||
@@ -175,8 +176,13 @@ sdk_init(
|
|||||||
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, add_toast)) {
|
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, add_toast)) {
|
||||||
v0->add_toast = sdk_add_toast;
|
v0->add_toast = sdk_add_toast;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of 0.2
|
// end of 0.2
|
||||||
|
|
||||||
|
if (v0->size >= RTL_SIZEOF_THROUGH_FIELD(SPICE_SDK_V0, insert_coin)) {
|
||||||
|
v0->insert_coin = sdk_insert_coin;
|
||||||
|
}
|
||||||
|
// end of 0.3
|
||||||
|
|
||||||
// any newer minor iterations will need to check the size
|
// any newer minor iterations will need to check the size
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -219,6 +225,7 @@ sdk_log(
|
|||||||
log_warning(facility_str.c_str(), "{}", message);
|
log_warning(facility_str.c_str(), "{}", message);
|
||||||
break;
|
break;
|
||||||
case SPICE_SDK_LOG_LEVEL_FATAL:
|
case SPICE_SDK_LOG_LEVEL_FATAL:
|
||||||
|
lock.unlock();
|
||||||
log_fatal(facility_str.c_str(), "{}", message);
|
log_fatal(facility_str.c_str(), "{}", message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -640,5 +647,21 @@ sdk_add_toast(
|
|||||||
return SPICE_SDK_STATUS_SUCCESS;
|
return SPICE_SDK_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SPICE_SDK_STATUS_CODE
|
||||||
|
__cdecl
|
||||||
|
sdk_insert_coin(
|
||||||
|
uint8_t amount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::shared_lock lock(sdk_global_mutex);
|
||||||
|
if (!sdk_initialized) {
|
||||||
|
return SPICE_SDK_STATUS_TOO_LATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount > 0) {
|
||||||
|
eamuse_coin_add(amount);
|
||||||
|
}
|
||||||
|
return SPICE_SDK_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sdk
|
} // namespace sdk
|
||||||
Reference in New Issue
Block a user