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

Rewrite extensions in Rust #467

Merged
merged 20 commits into from
Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/extensions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Extensions

on:
push:
paths:
- 'extensions/**'
- '.github/workflows/extensions.yml'
branches:
- '*'
tags:
- 'v*.*.*'
workflow_dispatch:

jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
from: libapollo_client.so
to: _x64.so
- target: x86_64-pc-windows-msvc
os: windows-latest
from: apollo_client.dll
to: _x64.dll
- target: i686-pc-windows-msvc
os: windows-latest
from: apollo_client.dll
to: .dll
runs-on: ${{ matrix.os }}
steps:
- name: Checkout the source code
uses: actions/checkout@v3
- name: Install Rust Target
run: |
rustup target add ${{ matrix.target }}
- name: Build
run: cd extensions && cargo build --target ${{ matrix.target }} --lib --release --verbose
- name: Move
run: mkdir release && cp extensions/target/${{ matrix.target }}/release/${{ matrix.from }} release/tac_apollo_client${{ matrix.to }}
- uses: actions/upload-artifact@v3
with:
name: extensions-${{ github.sha }}
path: release
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,6 @@ ArmaScriptCompiler.exe
texHeaders.bin
*.biprivatekey
keys/*

# Extensions
*.dll
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,16 @@ _Replace `hemtt` with `hemtt.exe` on Windows._
- Run `$ hemtt build` to create a development build (add `-f` to overwrite already built addons)
- Run `$ hemtt build --release` to create a release build (add `-f` to overwrite already built release)
- _Only Windows release builds are currently supported!_
- **Add extension builds from [CI](https://github.com/Theseus-Aegis/Mods/actions/workflows/extensions.yml)!**
- Run `$ hemtt clean` to clean build files

**Windows Helpers:**
- Double-click `build.bat` to create a development build

### Extensions

_Only Windows extension builds are currently supported!_

**Requirements:**
- Boost library (>= 1.74)
- _Precompiled for Windows available [here](https://sourceforge.net/projects/boost/files/boost-binaries/) (last tested: 1.74.0 MSVC 14.2)_
- `BOOST_ROOT` environment variable set to `<path>\boost_1_74_0` (or other version)
- [Windows] [Visual Studio 2017](https://visualstudio.microsoft.com/downloads/) (or higher)
- [Linux] `g++-w64-mingw-i686` for 64-bit
- Rust (>= 1.59)

Extensions builds must be invoked manually, as they do not get rebuild with every release:
- Run `$ hemtt run extensions`
Extensions builds must be invoked manually or via CI:
- Run `$ cargo build [--release]` in `extensions` directory
1 change: 1 addition & 0 deletions addons/apollo/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PREP(endMissionError);
PREP(getPlayerInfo);
PREP(handleDisconnect);
PREP(handleExtMultipartReturn);
PREP(handleKilled);
PREP(handleRespawn);
PREP(invokeJavaMethod);
Expand Down
41 changes: 10 additions & 31 deletions addons/apollo/functions/fnc_getPlayerInfo.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,19 @@ if (_playerUID isEqualTo "_SP_PLAYER_" || {_playerUID isEqualto "_SP_AI_"}) exit
[]
};

private _requestedInfo = [];
private _loadData = "tac_apollo_client" callExtension [_type, [_playerUID]];

TRACE_1("Loading Data",_player);
private _success = false;

private _loadData = "tac_apollo_client" callExtension format ["%1%2", _type, _playerUID];
TRACE_1("Load Data Start",_loadData);

if (_loadData == "loaded") then {
private _updateInfo = true;
while {_updateInfo} do {
private _loadData = "tac_apollo_client" callExtension "get";
TRACE_1("Load Data",_loadData);

if (_loadData == "error") then {
// Bad things happened, stop executing
_updateInfo = false;
} else {
if (_loadData == "done") then {
// Initialization complete
_updateInfo = false;
_success = true;
} else {
// Add data to array
_requestedInfo pushBack _loadData;
};
};
};
_loadData params ["_result", "_returnCode", "_errorCode"];
if (_result == "queued" && {_returnCode == 0} && {_errorCode == 0}) then {
_result = [] call FUNC(handleExtMultipartReturn);
};

if !(_success) exitWith {
ERROR_2("Failed to load info (Name: %1 - UID: %2)!",profileName,getPlayerUID _player);
if (_returnCode == 0 && {_errorCode == 0} && {_result != "error"}) then {
private _requestedInfo = parseSimpleArray _result;
TRACE_1("Player Info",_requestedInfo);
_requestedInfo
} else {
ERROR_4("Failed to load info (Name: %1 - UID: %2) [return: %3, error: %4]!",profileName,_playerUID,_returnCode,_errorCode);
[_errorMessage] call CBA_fnc_notify;
[]
};

_requestedInfo
44 changes: 44 additions & 0 deletions addons/apollo/functions/fnc_handleExtMultipartReturn.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "script_component.hpp"
/*
* Author: Jonpas
* Handles multipart return from an extension, concatenating the result for direct use in parseSimpleArray.
*
* Arguments:
* 0: Extension <STRING> (default: tac_apollo_client)
* 1: Fetch/Get Command <STRING> (default: get)
* 2: Expected Completed Return <STRING> (default: done)
* 3: Expected Error Return <STRING> (default: error)
*
* Return Value:
* Extension Result <STRING>
*
* Example:
* [] call tac_apollo_fnc_handleExtMultipartReturn
* ["tac_apollo_client", "get", "done", "error"] call tac_apollo_fnc_handleExtMultipartReturn
*
* Public: No
*/

params [["_ext", "tac_apollo_client"], ["_get", "get"], ["_completed", "done"], ["_error", "error"]];

private _results = [];
private _loading = true;

while {_loading} do {
private _loadData = _ext callExtension [_get, []];

_loadData params ["_result", "_returnCode", "_errorCode"];
if (_returnCode == 0 && {_errorCode == 0} && {_result != _error}) then {
if (_result == _completed) then {
_loading = false;
} else {
_results pushBack _result;
};
} else {
ERROR_4("Failure on multipart return (Ext: %1 - Command: %2) [return: %3, error: %4]!",_ext,_get,_returnCode,_errorCode);
_results = ["error"];
_loading = false;
};
};

_results joinString ""
42 changes: 18 additions & 24 deletions addons/apollo/functions/fnc_playerLoadClient.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,32 @@ params ["_player", "_loadType"];
_player allowDamage false;

TRACE_1("Loading Client",_player);
private _success = false;

// Don't load when UID is "_SP_PLAYER_" (singleplayer/editor)
if (getPlayerUID _player == "_SP_PLAYER_") exitWith {false};

private _loadData = "tac_apollo_client" callExtension format ["%1%2/%3", "loadPlayer", getPlayerUID _player, GVAR(isDebug)];
private _loadData = "tac_apollo_client" callExtension ["loadPlayer", [getPlayerUID _player, GVAR(isDebug)]];
TRACE_1("Load Data Start",_loadData);

if (_loadData == "loaded") then {
private _updateInfo = true;
while {_updateInfo} do {
private _loadData = "tac_apollo_client" callExtension "get";
TRACE_1("Load Data",_loadData);
_loadData params ["_result", "_returnCode", "_errorCode"];
if (_result == "queued" && {_returnCode == 0} && {_errorCode == 0}) then {
_result = [] call FUNC(handleExtMultipartReturn);
};

if (_returnCode == 0 && {_errorCode == 0} && {_result != "error"}) then {
private _playerData = parseSimpleArray _result;

_playerData params [["_dir", -1], ["_posASL", []], ["_loadout", []]];

if (_loadData == "error") then {
// Bad things happened, stop executing
_updateInfo = false;
} else {
if (_loadData == "done") then {
// Initialization complete
_updateInfo = false;
_success = true;
} else {
private _codePacket = _loadData select [17, count _loadData];
TRACE_1("Code Packet",_codePacket);
call (compile _codePacket);
};
};
if (_dir != -1) then {
_player setDir _dir;
};
};
if (_posASL isNotEqualTo [] && {count _posASL == 3}) then {
_player setPosASL _posASL;
};
_player setUnitLoadout _loadout;
_player setDamage 0;

if (_success) then {
// Goggles bandaid (#283 - vanilla bug) - setUnitLoadout does not properly set goggles (like dragging in inventory would)
private _goggles = goggles _player;
if (_goggles != "") then {
Expand All @@ -79,6 +73,6 @@ if (_success) then {

INFO_1("Client %1 successfully.",_loadType);
} else {
ERROR_2("Player load failed (Name: %1 - UID: %2)!",profileName,getPlayerUID _player);
ERROR_4("Player load failed (Name: %1 - UID: %2) [return: %3, error: %4]!",profileName,getPlayerUID _player,_returnCode,_errorCode);
["Your connection has been terminated - Error during Chronos loading!"] call FUNC(endMissionError);
};
2 changes: 1 addition & 1 deletion addons/apollo/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "\x\tac\addons\main\script_macros.hpp"

#define REQUIRED_JNI_VERSION "1.0.0"
#define REQUIRED_APOLLOCLIENT_VERSION "1.24.0.56"
#define REQUIRED_APOLLOCLIENT_VERSION "1.0.0"

#define SAVE_DELAY_PERIODIC 30
#define SAVE_DELAY_INV_CHANGE 10
40 changes: 7 additions & 33 deletions addons/armory/functions/fnc_getDataChronos.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -27,45 +27,19 @@ if !(["tac_apollo"] call ACEFUNC(common,isModLoaded)) exitWith {
private _debug = [false, true] select EGVAR(apollo,isDebug);
TRACE_2("Chronos Debug",EGVAR(apollo,isDebug),_debug);

private _success = false;
private _armoryData = [];
private _loadData = "tac_apollo_client" callExtension ["loadArmory", [_selectedCategory, getPlayerUID player, _debug]];

// Call Chronos for Data - no further HTTP calls are needed after this one
private _loadData = "tac_apollo_client" callExtension format ["%1%2/%3/%4", "loadArmory", _selectedCategory, getPlayerUID player, _debug];
if (_loadData == "loaded") then {
private _updateInfo = true;
private _entry = [];

while {_updateInfo} do {
// Retrieve the data which is stored in the client's heap
_loadData = "tac_apollo_client" callExtension "get";
TRACE_1("Get Chronos Data",_loadData);

if (_loadData == "error") then {
// Bad things happened, stop executing
_updateInfo = false;
} else {
if (_loadData == "done") then {
_updateInfo = false;
_success = true;
} else {
_entry pushBack _loadData;

// Reset
if (_loadData == "next") then {
_armoryData pushBack _entry;
_entry = [];
};
};
};
};
_loadData params ["_result", "_returnCode", "_errorCode"];
if (_result == "queued" && {_returnCode == 0} && {_errorCode == 0}) then {
_result = [] call EFUNC(apollo,handleExtMultipartReturn);
};

if (_success) then {
if (_returnCode == 0 && {_errorCode == 0} && {_result != "error"}) then {
private _armoryData = parseSimpleArray _result;
TRACE_2("Athena Armory Data",_selectedCategory,_armoryData);
_armoryData
} else {
ERROR("Armory data failed to load!");
ERROR_2("Armory data failed to load [return: %1, error: %2]!",_returnCode,_errorCode);
[LSTRING(ChronosError), 2.5] call ACEFUNC(common,displayTextStructured);
false
};
13 changes: 11 additions & 2 deletions extensions/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
Win32/*
x64/*
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# These are backup files generated by rustfmt
**/*.rs.bk


# Logs
logs/
73 changes: 0 additions & 73 deletions extensions/CMakeLists.txt

This file was deleted.

Loading