Graph map thingy

This commit is contained in:
IQuant 2024-06-21 19:06:40 +03:00
parent 4d9376205c
commit d799a95068
10 changed files with 162 additions and 43 deletions

10
noita-proxy/Cargo.lock generated
View file

@ -924,6 +924,15 @@ dependencies = [
"web-sys",
]
[[package]]
name = "egui_plot"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7854b86dc1c2d352c5270db3d600011daa913d6b554141a03939761323288a1"
dependencies = [
"egui",
]
[[package]]
name = "ehttp"
version = "0.5.0"
@ -1932,6 +1941,7 @@ dependencies = [
"eframe",
"egui-file-dialog",
"egui_extras",
"egui_plot",
"fluent-bundle",
"fluent-templates",
"image",

View file

@ -38,6 +38,7 @@ rustc-hash = "1.1.0"
fluent-templates = "0.9.4"
unic-langid = { version = "0.9.5", features = ["serde"] }
fluent-bundle = "0.15.3"
egui_plot = "0.27.2"
[profile.dev]
opt-level = 1

View file

@ -11,6 +11,7 @@ use eframe::egui::{
self, Align2, Button, Color32, InnerResponse, Key, Margin, OpenUrl, Rect, RichText,
TextureOptions, Ui, Vec2,
};
use egui_plot::{Plot, Points};
use lang::{set_current_locale, tr, LANGS};
use mod_manager::{Modmanager, ModmanagerSettings};
use net::{omni::PeerVariant, NetManagerInit};
@ -22,7 +23,6 @@ use tracing::info;
use unic_langid::LanguageIdentifier;
pub mod lang;
pub mod messages;
mod mod_manager;
pub mod net;
pub mod releases;
@ -425,8 +425,18 @@ impl eframe::App for App {
let _ = ctx.set_contents(id.raw().to_string());
}
}
} else {
ui.label(format!("Peer state: {}", netman.peer.state()));
}
ui.label(format!("Peer state: {}", netman.peer.state()));
let mut series = Vec::new();
netman.world_info.with_player_infos(|_peer, info| {
series.push([info.x, -info.y]);
});
let points = Points::new(series);
Plot::new("map").show(ui, |plot| {
plot.points(points);
})
});
}
AppState::Error { message } => {

View file

@ -1,3 +1,5 @@
use messages::NetMsg;
use omni::OmniPeerId;
use socket2::{Domain, Socket, Type};
use std::{
env,
@ -9,14 +11,15 @@ use std::{
time::Duration,
};
use tracing::debug;
use world::{NoitaWorldUpdate, WorldManager};
use world::{world_info::WorldInfo, NoitaWorldUpdate, WorldManager};
use tangled::Reliability;
use tracing::{error, info, warn};
use tungstenite::{accept, WebSocket};
use crate::{messages::NetMsg, GameSettings};
use crate::GameSettings;
pub mod messages;
pub mod steam_networking;
pub mod world;
@ -81,6 +84,7 @@ pub struct NetManager {
pub stopped: AtomicBool,
pub error: Mutex<Option<io::Error>>,
pub init_settings: NetManagerInit,
pub world_info: WorldInfo,
}
impl NetManager {
@ -99,6 +103,7 @@ impl NetManager {
stopped: AtomicBool::new(false),
error: Default::default(),
init_settings: init,
world_info: Default::default(),
}
.into()
}
@ -303,44 +308,7 @@ impl NetManager {
match msg {
Ok(msg) => {
if let tungstenite::Message::Binary(msg) = msg {
match msg[0] & 0b11 {
// Message to proxy
1 => {
self.handle_message_to_proxy(&msg[1..]);
}
// Broadcast
2 => {
let msg_to_send = if false {
let compressed = lz4_flex::compress_prepend_size(&msg[1..]);
debug!(
"Compressed {} bytes to {} bytes",
msg.len(),
compressed.len()
);
NetMsg::ModCompressed { data: compressed }
} else {
NetMsg::ModRaw {
data: msg[1..].to_owned(),
}
};
let reliable = msg[0] & 4 > 0;
self.broadcast(
&msg_to_send,
if reliable {
Reliability::Reliable
} else {
Reliability::Unreliable
},
);
}
// Binary message to proxy
3 => self.handle_bin_message_to_proxy(&msg[1..], state),
msg_variant => {
error!("Unknown msg variant from mod: {}", msg_variant)
}
}
self.handle_mod_message_2(msg, state);
}
}
Err(tungstenite::Error::Io(io_err))
@ -353,6 +321,47 @@ impl NetManager {
}
}
fn handle_mod_message_2(&self, msg: Vec<u8>, state: &mut NetInnerState) {
match msg[0] & 0b11 {
// Message to proxy
1 => {
self.handle_message_to_proxy(&msg[1..]);
}
// Broadcast
2 => {
let msg_to_send = if false {
let compressed = lz4_flex::compress_prepend_size(&msg[1..]);
debug!(
"Compressed {} bytes to {} bytes",
msg.len(),
compressed.len()
);
NetMsg::ModCompressed { data: compressed }
} else {
NetMsg::ModRaw {
data: msg[1..].to_owned(),
}
};
let reliable = msg[0] & 4 > 0;
self.broadcast(
&msg_to_send,
if reliable {
Reliability::Reliable
} else {
Reliability::Unreliable
},
);
}
// Binary message to proxy
3 => self.handle_bin_message_to_proxy(&msg[1..], state),
msg_variant => {
error!("Unknown msg variant from mod: {}", msg_variant)
}
}
}
pub fn start(self: Arc<NetManager>) {
info!("Starting netmanager");
thread::spawn(move || {
@ -395,6 +404,14 @@ impl NetManager {
self.resend_game_settings();
}
}
Some("peer_pos") => {
let peer_id = msg.next().and_then(OmniPeerId::from_hex);
let x: Option<f64> = msg.next().and_then(|s| s.parse().ok());
let y: Option<f64> = msg.next().and_then(|s| s.parse().ok());
if let (Some(peer_id), Some(x), Some(y)) = (peer_id, x, y) {
self.world_info.update_player_pos(peer_id, x, y);
}
}
key => {
error!("Unknown msg from mod: {:?}", key)
}

View file

@ -3,7 +3,7 @@ use std::fmt::Display;
use steamworks::{LobbyId, SteamId};
use tangled::{PeerId, PeerState, Reliability};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OmniPeerId(pub u64);
impl From<PeerId> for OmniPeerId {
@ -41,6 +41,13 @@ impl Display for OmniPeerId {
}
}
impl OmniPeerId {
pub fn from_hex(val: &str) -> Option<Self> {
let raw = u64::from_str_radix(val, 16).ok()?;
Some(Self(raw))
}
}
pub enum OmniNetworkEvent {
PeerConnected(OmniPeerId),
PeerDisconnected(OmniPeerId),

View file

@ -6,6 +6,7 @@ use world_model::{ChunkDelta, WorldModel};
pub use world_model::encoding::NoitaWorldUpdate;
pub mod world_info;
pub mod world_model;
#[derive(Debug, Serialize, Deserialize)]

View file

@ -0,0 +1,45 @@
use std::sync::{Arc, Mutex};
use rustc_hash::FxHashMap;
use crate::net::omni::OmniPeerId;
#[derive(Default, Clone, Copy)]
pub struct PlayerInfo {
pub x: f64,
pub y: f64,
}
#[derive(Default)]
struct WorldInfoInner {
players: FxHashMap<OmniPeerId, PlayerInfo>,
}
#[derive(Default)]
pub struct WorldInfo {
inner: Arc<Mutex<WorldInfoInner>>,
}
impl WorldInfo {
fn with_inner<T>(&self, f: impl FnOnce(&mut WorldInfoInner) -> T) -> T {
let mut inner = self.inner.lock().unwrap();
f(&mut inner)
}
pub(in crate::net) fn update_player_pos(&self, peer_id: OmniPeerId, x: f64, y: f64) {
self.with_inner(|inner| {
let info = inner.players.entry(peer_id).or_default();
// info.peer_id = peer_id;
info.x = x;
info.y = y;
})
}
pub fn with_player_infos(&self, mut f: impl FnMut(OmniPeerId, PlayerInfo)) {
self.with_inner(|inner| {
for (id, info) in &inner.players {
f(*id, *info)
}
})
}
}

View file

@ -0,0 +1,27 @@
local world_ffi = require("noitapatcher.nsew.world_ffi")
local world = require("noitapatcher.nsew.world")
local rect = require("noitapatcher.nsew.rect")
local ffi = require("ffi")
local ctx = dofile_once("mods/quant.ew/files/src/ctx.lua")
local net = dofile_once("mods/quant.ew/files/src/net.lua")
local player_fns = dofile_once("mods/quant.ew/files/src/player_fns.lua")
local module = {}
local KEY_WORLD_FRAME = 0
local KEY_WORLD_END = 1
local CHUNK_SIZE = 128
function module.on_world_update_host()
if GameGetFrameNum() % 60 ~= 6 then
return
end
for peer_id, player_data in pairs(ctx.players) do
local x, y = EntityGetTransform(player_data.entity)
net.proxy_send("peer_pos", peer_id.." "..x.." "..y)
end
end
return module

View file

@ -51,6 +51,7 @@ local function load_modules()
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/heart_pickups/sync.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/spawn_hooks/init.lua")
ctx.dofile_and_add_hooks("mods/quant.ew/files/src/system/proxy_info.lua")
end
function OnProjectileFired(shooter_id, projectile_id, initial_rng, position_x, position_y, target_x, target_y, send_message,