mirror of
https://github.com/jugeeya/UltimateTrainingModpack.git
synced 2025-04-26 23:49:18 +00:00
Add Firebase logging via HTTPS (#248)
* trying * trying * try with json to compile * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * Update Cargo.toml * Update lib.rs * Update Cargo.toml * further testing * continually testing * simplify * remove unnecessary diffs * working! * Use cargo-skyline image with devkitpro * Update rust.yml * Update rust.yml * Remove clippy PR for now
This commit is contained in:
parent
5ac46b4d29
commit
198bf23031
7 changed files with 225 additions and 24 deletions
44
.github/workflows/rust.yml
vendored
44
.github/workflows/rust.yml
vendored
|
@ -8,32 +8,33 @@ on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
clippy_pr:
|
# clippy_pr:
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
steps:
|
# container: devkitpro/devkita64
|
||||||
- uses: actions/checkout@v2
|
# steps:
|
||||||
- name: Install minimal nightly rust
|
# - uses: actions/checkout@v2
|
||||||
uses: actions-rs/toolchain@v1
|
# - name: Install minimal nightly rust
|
||||||
with:
|
# uses: actions-rs/toolchain@v1
|
||||||
profile: minimal
|
# with:
|
||||||
toolchain: nightly-2021-06-01
|
# profile: minimal
|
||||||
components: rustfmt, clippy
|
# toolchain: nightly-2021-06-01
|
||||||
default: true
|
# components: rustfmt, clippy
|
||||||
target: x86_64-unknown-linux-gnu
|
# default: true
|
||||||
- uses: actions-rs/clippy-check@v1
|
# target: x86_64-unknown-linux-gnu
|
||||||
with:
|
# - uses: actions-rs/clippy-check@v1
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
# with:
|
||||||
toolchain: nightly-2021-06-01
|
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
args: --all-features --target=x86_64-unknown-linux-gnu
|
# toolchain: nightly-2021-06-01
|
||||||
|
# args: --all-features --target=x86_64-unknown-linux-gnu
|
||||||
plugin:
|
plugin:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: jugeeya/cargo-skyline:2.1.0
|
image: jugeeya/cargo-skyline:2.1.0-dkp
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Build release NRO
|
- name: Build release NRO
|
||||||
run: |
|
run: |
|
||||||
PATH=$PATH:/root/.cargo/bin /root/.cargo/bin/cargo-skyline skyline build --release
|
PATH=$PATH:/root/.cargo/bin:/opt/devkitpro/devkitA64/bin /root/.cargo/bin/cargo-skyline skyline build --release
|
||||||
env:
|
env:
|
||||||
HOME: /root
|
HOME: /root
|
||||||
- name: Upload plugin artifact
|
- name: Upload plugin artifact
|
||||||
|
@ -50,11 +51,12 @@ jobs:
|
||||||
if: github.ref == 'refs/heads/master'
|
if: github.ref == 'refs/heads/master'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: jugeeya/cargo-skyline:2.1.0
|
image: jugeeya/cargo-skyline:2.1.0-dkp
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Build outside_training_mode NRO
|
- name: Build outside_training_mode NRO
|
||||||
run: PATH=$PATH:/root/.cargo/bin /root/.cargo/bin/cargo-skyline skyline build --features outside_training_mode
|
run: |
|
||||||
|
PATH=$PATH:/root/.cargo/bin:/opt/devkitpro/devkitA64/bin /root/.cargo/bin/cargo-skyline skyline build --release
|
||||||
env:
|
env:
|
||||||
HOME: /root
|
HOME: /root
|
||||||
- name: Upload plugin (outside training mode) artifact
|
- name: Upload plugin (outside training mode) artifact
|
||||||
|
|
|
@ -25,7 +25,13 @@ num-traits = "0.2"
|
||||||
wsl = "0.1.0"
|
wsl = "0.1.0"
|
||||||
strum = "0.21.0"
|
strum = "0.21.0"
|
||||||
strum_macros = "0.21.0"
|
strum_macros = "0.21.0"
|
||||||
rand = { git = "https://github.com/skyline-rs/rand" }
|
minreq = { version = "=2.2.1", features = ["https", "json-using-serde"] }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
ring = { git = "https://github.com/skyline-rs/ring", branch = "0.16.20" }
|
||||||
|
webpki = { git = "https://github.com/skyline-rs/webpki" }
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
|
162
src/common/events.rs
Normal file
162
src/common/events.rs
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use skyline::libc::c_void;
|
||||||
|
use skyline::nn::{crypto, account, time, oe};
|
||||||
|
use core::lazy::OnceCell;
|
||||||
|
|
||||||
|
pub static mut EVENT_QUEUE: Vec<Event> = vec![];
|
||||||
|
static mut SESSION_ID: OnceCell<String> = OnceCell::new();
|
||||||
|
static mut DEVICE_ID: OnceCell<String> = OnceCell::new();
|
||||||
|
static mut USER_ID: OnceCell<String> = OnceCell::new();
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
|
pub struct Event {
|
||||||
|
pub event_name: String,
|
||||||
|
pub user_id: String,
|
||||||
|
pub device_id: String,
|
||||||
|
pub event_time: u128,
|
||||||
|
pub session_id: String,
|
||||||
|
pub menu_settings: String,
|
||||||
|
pub mod_version: String,
|
||||||
|
pub smash_version: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#[link_name = "\u{1}_ZN2nn2oe17GetPseudoDeviceIdEPNS_4util4UuidE"]
|
||||||
|
pub fn GetPseudoDeviceId(arg1: *mut Uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Uuid {
|
||||||
|
Size: u32,
|
||||||
|
StringSize: u32,
|
||||||
|
data: [u8; 16]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Uuid {
|
||||||
|
pub fn to_str(&self) -> String {
|
||||||
|
self.data
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| format!("{:02x}", i))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Sha256Hash {
|
||||||
|
hash: [u8; 0x20]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Event {
|
||||||
|
pub fn new() -> Event {
|
||||||
|
let mut device_uuid = Uuid{
|
||||||
|
Size: 16,
|
||||||
|
StringSize: 300,
|
||||||
|
data: [0u8; 16]
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
GetPseudoDeviceId(&mut device_uuid as *mut Uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut time = skyline::nn::time::PosixTime{
|
||||||
|
time: 0
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
time::Initialize();
|
||||||
|
let event_time = SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time went backwards")
|
||||||
|
.as_millis();
|
||||||
|
|
||||||
|
let mut smash_version = oe::DisplayVersion{
|
||||||
|
name: [0 as skyline::libc::c_char; 16]
|
||||||
|
};
|
||||||
|
oe::GetDisplayVersion(&mut smash_version);
|
||||||
|
if SESSION_ID.get().is_none() {
|
||||||
|
account::Initialize();
|
||||||
|
let mut user_uid = account::Uid::new();
|
||||||
|
account::GetLastOpenedUser(&mut user_uid);
|
||||||
|
|
||||||
|
let mut user_id_hash = Sha256Hash{
|
||||||
|
hash: [0; 0x20]
|
||||||
|
};
|
||||||
|
crypto::GenerateSha256Hash(
|
||||||
|
&mut user_id_hash as *mut _ as *mut c_void,
|
||||||
|
0x20 * 8,
|
||||||
|
user_uid.id.as_ptr() as *const c_void,
|
||||||
|
16 * 8);
|
||||||
|
|
||||||
|
USER_ID.set(
|
||||||
|
user_uid.id
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| format!("{:02x}", i))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
let mut device_id_hash = Sha256Hash{
|
||||||
|
hash: [0; 0x20]
|
||||||
|
};
|
||||||
|
crypto::GenerateSha256Hash(
|
||||||
|
&mut device_id_hash as *mut _ as *mut c_void,
|
||||||
|
0x20 * 8,
|
||||||
|
device_uuid.data.as_ptr() as *const c_void,
|
||||||
|
64 * 2);
|
||||||
|
DEVICE_ID.set(
|
||||||
|
device_uuid.data
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| format!("{:02x}", i))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")
|
||||||
|
).unwrap();
|
||||||
|
|
||||||
|
|
||||||
|
let mut session_id_hash = Sha256Hash{
|
||||||
|
hash: [0; 0x20]
|
||||||
|
};
|
||||||
|
// let mut device_id_0_bytes : [u8; 8] = Default::default();
|
||||||
|
// device_id_0_bytes.copy_from_slice(&device_uuid.data[0..8]);
|
||||||
|
// let mut device_id_1_bytes : [u8; 8] = Default::default();
|
||||||
|
// device_id_1_bytes.copy_from_slice(&device_uuid.data[8..16]);
|
||||||
|
let event_time_bytes : [u8; 16] = std::mem::transmute(event_time.to_be());
|
||||||
|
let session_id_bytes : [u8; 32] = [
|
||||||
|
event_time_bytes, device_uuid.data
|
||||||
|
].concat().try_into().unwrap();
|
||||||
|
|
||||||
|
crypto::GenerateSha256Hash(
|
||||||
|
&mut session_id_hash as *mut _ as *mut c_void,
|
||||||
|
0x20 * 8,
|
||||||
|
session_id_bytes.as_ptr() as *const c_void,
|
||||||
|
32 * 8);
|
||||||
|
SESSION_ID.set(session_id_hash.hash
|
||||||
|
.into_iter()
|
||||||
|
.map(|i| format!("{:02x}", i))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("")).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut event = Event::default();
|
||||||
|
event.user_id = USER_ID.get().unwrap().to_string();
|
||||||
|
event.device_id = DEVICE_ID.get().unwrap().to_string();
|
||||||
|
event.event_time = event_time;
|
||||||
|
event.session_id = SESSION_ID.get().unwrap().to_string();
|
||||||
|
event.mod_version = crate::common::release::CURRENT_VERSION.to_string();
|
||||||
|
event.smash_version = std::ffi::CStr::from_ptr(smash_version.name.as_ptr() as *const i8).to_owned().to_str().unwrap().to_string();
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn smash_open() -> Event {
|
||||||
|
let mut event = Event::new();
|
||||||
|
event.event_name = "SMASH_OPEN".to_string();
|
||||||
|
event
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn menu_open(menu_settings: String) -> Event {
|
||||||
|
let mut event = Event::new();
|
||||||
|
event.event_name = "MENU_OPEN".to_string();
|
||||||
|
event.menu_settings = menu_settings;
|
||||||
|
event
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ use smash::lib::lua_const::*;
|
||||||
use skyline_web::{Background, BootDisplay, Webpage};
|
use skyline_web::{Background, BootDisplay, Webpage};
|
||||||
use ramhorns::{Template, Content};
|
use ramhorns::{Template, Content};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
use crate::events::{Event, EVENT_QUEUE};
|
||||||
use crate::training::frame_counter;
|
use crate::training::frame_counter;
|
||||||
|
|
||||||
static mut FRAME_COUNTER_INDEX: usize = 0;
|
static mut FRAME_COUNTER_INDEX: usize = 0;
|
||||||
|
@ -363,4 +364,7 @@ pub unsafe fn spawn_menu() {
|
||||||
let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.conf";
|
let menu_conf_path = "sd:/TrainingModpack/training_modpack_menu.conf";
|
||||||
std::fs::write(menu_conf_path, last_url)
|
std::fs::write(menu_conf_path, last_url)
|
||||||
.expect("Failed to write menu conf file");
|
.expect("Failed to write menu conf file");
|
||||||
|
unsafe {
|
||||||
|
EVENT_QUEUE.push(Event::menu_open(last_url.to_string()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
|
pub mod events;
|
||||||
pub mod menu;
|
pub mod menu;
|
||||||
pub mod release;
|
pub mod release;
|
||||||
pub mod raygun_printer;
|
pub mod raygun_printer;
|
||||||
|
|
||||||
use crate::common::consts::*;
|
use crate::common::consts::*;
|
||||||
|
use crate::common::events::*;
|
||||||
use smash::app::{self, lua_bind::*};
|
use smash::app::{self, lua_bind::*};
|
||||||
use smash::hash40;
|
use smash::hash40;
|
||||||
use smash::lib::lua_const::*;
|
use smash::lib::lua_const::*;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use skyline_web::DialogOk;
|
use skyline_web::DialogOk;
|
||||||
const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt";
|
const VERSION_FILE_PATH: &str = "sd:/TrainingModpack/version.txt";
|
||||||
|
|
||||||
fn is_current_version(fpath: &str) -> bool {
|
fn is_current_version(fpath: &str) -> bool {
|
||||||
|
|
27
src/lib.rs
27
src/lib.rs
|
@ -2,6 +2,7 @@
|
||||||
#![feature(with_options)]
|
#![feature(with_options)]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(exclusive_range_pattern)]
|
#![feature(exclusive_range_pattern)]
|
||||||
|
#![feature(once_cell)]
|
||||||
#![allow(clippy::borrow_interior_mutable_const, clippy::not_unsafe_ptr_arg_deref, clippy::missing_safety_doc, clippy::wrong_self_convention)]
|
#![allow(clippy::borrow_interior_mutable_const, clippy::not_unsafe_ptr_arg_deref, clippy::missing_safety_doc, clippy::wrong_self_convention)]
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
@ -19,6 +20,7 @@ extern crate bitflags;
|
||||||
extern crate num_derive;
|
extern crate num_derive;
|
||||||
|
|
||||||
use crate::common::*;
|
use crate::common::*;
|
||||||
|
use crate::events::{Event, EVENT_QUEUE};
|
||||||
use crate::menu::set_menu_from_url;
|
use crate::menu::set_menu_from_url;
|
||||||
|
|
||||||
use skyline::libc::mkdir;
|
use skyline::libc::mkdir;
|
||||||
|
@ -48,7 +50,6 @@ macro_rules! c_str {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(test))]
|
|
||||||
#[skyline::main(name = "training_modpack")]
|
#[skyline::main(name = "training_modpack")]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
macro_rules! log {
|
macro_rules! log {
|
||||||
|
@ -59,6 +60,10 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
log!("Initialized.");
|
log!("Initialized.");
|
||||||
|
unsafe {
|
||||||
|
EVENT_QUEUE.push(Event::smash_open());
|
||||||
|
}
|
||||||
|
|
||||||
hitbox_visualizer::hitbox_visualization();
|
hitbox_visualizer::hitbox_visualization();
|
||||||
hazard_manager::hazard_manager();
|
hazard_manager::hazard_manager();
|
||||||
training::training_mods();
|
training::training_mods();
|
||||||
|
@ -85,4 +90,24 @@ pub fn main() {
|
||||||
set_menu_from_url(std::str::from_utf8(&menu_conf).unwrap());
|
set_menu_from_url(std::str::from_utf8(&menu_conf).unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::thread::spawn(||{
|
||||||
|
loop {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(5));
|
||||||
|
unsafe {
|
||||||
|
while let Some(event) = EVENT_QUEUE.pop() {
|
||||||
|
let host = "https://my-project-1511972643240-default-rtdb.firebaseio.com";
|
||||||
|
let path = format!("/event/{}/device/{}/{}.json",
|
||||||
|
event.event_name, event.device_id, event.event_time);
|
||||||
|
|
||||||
|
let url = format!("{}{}", host, path);
|
||||||
|
minreq::post(url)
|
||||||
|
.with_json(&event)
|
||||||
|
.unwrap()
|
||||||
|
.send()
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue