Heyo @Desdaemon, I put together some of what we spoke earlier about this feature:
Simple Communication System + YNOP Data receiver for EasyRPG
Allows the player to recieve or send data to the server
1. Basic Operations
GET Operation (0)
// Client sends:
{
"request": "path/to/data",
"type": 0, // GET operation
}
// Server responds:
{
"status": "ok",
"data": "string_value" // Converted based on target_type
}
SET Operation (1)
// Client sends:
{
"request": "path/to/data",
"type": 1, // SET operation
"data": "string_value", // Value to set
}
// Server responds:
{
"status": "ok",
"error": null // Optional: contains error message if status is "error"
}
2. Other Features
Player Data Operations
// GET Player Name: "player/name"
Request:
{
"request": "player/name",
"type": 0
}
Response:
{
"status": "ok",
"data": "PlayerName"
}
3. Error Handling
// Error Response Format
{
"status": "error",
"error": "Detailed error message",
"code": 404 // Optional: HTTP-style error code
}
// Common Error Types
{
"status": "error",
"error": "File not found",
"code": 404
}
{
"status": "error",
"error": "Invalid JSON format",
"code": 400
}
4. Command Structure (5000)
(Just for reference, code is almost pseudo-code)
//Inside GAME_INTERPRETER.CPP edit ExecuteCommand:
bool Game_Interpreter::ExecuteCommand(lcf::rpg::EventCommand const& com) {
switch (static_cast<Cmd>(com.code)) {
case static_cast<Cmd>(5000): // or "Cmd::YNOP_Bridge" If you want to mess with liblcf
return CommandYNOPBridge(com);
}
}
// Then add this method:
bool Game_Interpreter::CommandYNOPBridge(lcf::rpg::EventCommand const& com) { //5000
std::string request_path = ToString(CommandStringOrVariable(com, 8, 9));
int operation = ValueOrVariable(com.parameters[0], com.parameters[1]);
int source_var_id = ValueOrVariable(com.parameters[2], com.parameters[3]);
int target_type = ValueOrVariable(com.parameters[4], com.parameters[5]);
int target_var_id = ValueOrVariable(com.parameters[6], com.parameters[7]);
std::stringstream json;
if (operation == 0) { //get
json << "{"
<< "\"request\":\"" << request_path << "\","
<< "\"type\":" << operation
<< "}";
std::string response = ProcessBridgeRequest(json.str()); // Process GET request
// Handle the response
if (!response.empty()) {
switch (target_type) {
case 0: // Switch
Main_Data::game_switches->Set(target_var_id, atoi(response.c_str()) != 0);
break;
case 1: // Variable
Main_Data::game_variables->Set(target_var_id, atoi(response.c_str()));
break;
case 2: // String
Main_Data::game_strings->Set(target_var_id, response);
break;
default:
Output::Warning("CommandYNOPBridge: Unsupported target_type {}", target_type);
return true;
}
}
}
if (operation == 1) { //set
std::string value_data;
switch (target_type) {
case 0: // Switch
value_data = std::to_string(Main_Data::game_switches->Get(target_var_id));
break;
case 1: // Variable
value_data = std::to_string(Main_Data::game_variables->Get(target_var_id));
break;
case 2: // String
value_data = ToString(Main_Data::game_strings->Get(target_var_id));
break;
default:
Output::Warning("CommandYNOPBridge: Unsupported target_type {}", target_type);
return true;
}
json << "{"
<< "\"request\":\"" << request_path << "\","
<< "\"type\":" << operation << ","
<< "\"data\":\"" << value_data << "\""
<< "}";
std::string response = ProcessBridgeRequest(json.str()); // Process SET request
// Handle response status if needed (stored in target_var_id)
if (!response.empty() && target_var_id > 0) {
Main_Data::game_strings->Set(target_var_id, response);
}
}
return true;
}
5. Storage Guidelines
Server-Side Storage
- Use flat file storage for JSON data
- One file per map/player/configuration
- Directory structure matches request paths
- Example:
cu/playermaps/PlayerName/mapname.json
- File Operations
- Read entire file for GET operations
- Write atomic updates for SET operations
- Use file locking for concurrent access
- Basic Validation
- Check for Logged Players
- Check JSON syntax
- Verify required fields
- Validate data types
Client-Side Handling
- Variable Types
- Switches (0): Boolean values
- Variables (1): Numeric values
- Strings (2): Text and JSON data
Heyo @Desdaemon, I put together some of what we spoke earlier about this feature:
Simple Communication System + YNOP Data receiver for EasyRPG
Allows the player to recieve or send data to the server
1. Basic Operations
GET Operation (0)
SET Operation (1)
2. Other Features
Player Data Operations
3. Error Handling
4. Command Structure (5000)
(Just for reference, code is almost pseudo-code)
5. Storage Guidelines
Server-Side Storage
cu/playermaps/PlayerName/mapname.jsonClient-Side Handling