Skip to content

Commit

Permalink
first (not quite functional) combat based on sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
greaka committed Jun 26, 2019
1 parent d09090d commit 3318dc0
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 21 deletions.
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ version = "0.1.0"
authors = ["Greaka <mrgreaka@gmail.com>"]
edition = "2018"

[dependencies]
arcdps_bindings = { version = "0.1.2", git = "https://github.com/greaka/arcdps_bindings" }
[dependencies.arcdps_bindings]
version = "0.1.3"
git = "https://github.com/greaka/arcdps_bindings"
# path="../arcdps_bindings"

[dependencies.winapi]
version = "0.3.7"
Expand Down
20 changes: 20 additions & 0 deletions src/device/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
mod worker;

use worker::{ChannelType, Device};

static mut DEVICE: Option<Device> = None;

pub fn gen_device() {
let device = Device::new("127.0.0.1:8214");
unsafe {
DEVICE = Some(device);
}
}

pub fn send_to_device(func: ChannelType) {
unsafe {
if let Some(d) = &DEVICE {
let _ = d.send(func);
}
}
}
32 changes: 32 additions & 0 deletions src/device/worker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::io::prelude::*;
use std::net::TcpStream;
use std::sync::mpsc;
pub type ChannelType = Vec<u8>;

pub struct Device {
sender: mpsc::Sender<ChannelType>,
}

impl Device {
pub fn new(connection_string: &'static str) -> Device {
let (tx, rx) = mpsc::channel();
let device = Device { sender: tx };
std::thread::spawn(move || loop {
let func = rx.recv().unwrap();
if let Ok(mut stream) = TcpStream::connect(connection_string) {
let bytes = build_array(func.as_ref());
let _ = stream.write(bytes.as_ref());
}
});

device
}

pub fn send(&self, func: ChannelType) -> Result<(), mpsc::SendError<ChannelType>> {
self.sender.send(func)
}
}

fn build_array(bytes: &[u8]) -> Vec<u8> {
[&bytes.len().to_le_bytes(), bytes].concat()
}
123 changes: 115 additions & 8 deletions src/exports/combat.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,118 @@
use arcdps_bindings::*;

use crate::device::send_to_device;
use arcdps_bindings::{cbtevent, Ag};
pub fn cbt(
_ev: Option<&cbtevent>,
_src: Option<&Ag>,
_dst: Option<&Ag>,
_skillname: Option<&str>,
_id: u64,
_revision: u64,
ev: Option<&cbtevent>,
src: Option<&Ag>,
dst: Option<&Ag>,
skillname: Option<&str>,
id: u64,
revision: u64,
) {
let message = get_bytes(ev, src, dst, skillname, id, revision);
send_to_device(message);
}

fn get_bytes(
ev: Option<&cbtevent>,
src: Option<&Ag>,
dst: Option<&Ag>,
skillname: Option<&str>,
id: u64,
revision: u64,
) -> Vec<u8> {
let mut messages = 0;
let mut message = Vec::new();
message.push(2); // indicator for combat message
if let Some(ev) = ev {
messages |= 1;
let mut bytes = get_ev_bytes(ev);
message.append(&mut bytes);
};
if let Some(ag) = src {
messages |= 1 << 1;
let mut bytes = get_ag_bytes(ag);
message.append(&mut bytes);
};
if let Some(ag) = dst {
messages |= 1 << 2;
let mut bytes = get_ag_bytes(ag);
message.append(&mut bytes);
};
if let Some(name) = skillname {
messages |= 1 << 3;
let bytes = name.as_bytes();
let mut bytes = [&bytes.len().to_le_bytes(), bytes].concat();
message.append(&mut bytes);
};
message.insert(1, messages);
message.append(&mut id.to_le_bytes().to_vec());
message.append(&mut revision.to_le_bytes().to_vec());
message
}

fn get_ev_bytes(ev: &cbtevent) -> Vec<u8> {
ev.time
.to_le_bytes()
.iter()
.chain(ev.src_agent.to_le_bytes().iter())
.chain(ev.dst_agent.to_le_bytes().iter())
.chain(ev.value.to_le_bytes().iter())
.chain(ev.buff_dmg.to_le_bytes().iter())
.chain(ev.overstack_value.to_le_bytes().iter())
.chain(ev.skillid.to_le_bytes().iter())
.chain(ev.src_instid.to_le_bytes().iter())
.chain(ev.dst_instid.to_le_bytes().iter())
.chain(ev.src_master_instid.to_le_bytes().iter())
.chain(ev.dst_master_instid.to_le_bytes().iter())
.chain(ev.iff.to_le_bytes().iter())
.chain(ev.buff.to_le_bytes().iter())
.chain(ev.result.to_le_bytes().iter())
.chain(ev.is_activation.to_le_bytes().iter())
.chain(ev.is_buffremove.to_le_bytes().iter())
.chain(ev.is_ninety.to_le_bytes().iter())
.chain(ev.is_fifty.to_le_bytes().iter())
.chain(ev.is_moving.to_le_bytes().iter())
.chain(ev.is_statechange.to_le_bytes().iter())
.chain(ev.is_flanking.to_le_bytes().iter())
.chain(ev.is_shields.to_le_bytes().iter())
.chain(ev.is_offcycle.to_le_bytes().iter())
.chain(ev.pad61.to_le_bytes().iter())
.chain(ev.pad62.to_le_bytes().iter())
.chain(ev.pad63.to_le_bytes().iter())
.chain(ev.pad64.to_le_bytes().iter())
.cloned()
.collect::<Vec<u8>>()
}

fn get_ag_bytes(ag: &Ag) -> Vec<u8> {
let (string_length, name_bytes) = if let Some(name) = ag.name {
let bytes = name.as_bytes();
(bytes.len(), Some(bytes))
} else {
(0, None)
};
if let Some(name_bytes) = name_bytes {
string_length
.to_le_bytes()
.iter()
.chain(name_bytes.iter())
.chain(ag.id.to_le_bytes().iter())
.chain(ag.prof.to_le_bytes().iter())
.chain(ag.elite.to_le_bytes().iter())
.chain(ag.self_.to_le_bytes().iter())
.chain(ag.team.to_le_bytes().iter())
.cloned()
.collect()
} else {
string_length
.to_le_bytes()
.iter()
.chain(ag.id.to_le_bytes().iter())
.chain(ag.prof.to_le_bytes().iter())
.chain(ag.elite.to_le_bytes().iter())
.chain(ag.self_.to_le_bytes().iter())
.chain(ag.team.to_le_bytes().iter())
.cloned()
.collect()
}
}
26 changes: 19 additions & 7 deletions src/exports/mod.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
mod combat;

use crate::device::send_to_device;
use arcdps_bindings::*;
use std::io::prelude::*;
use std::net::TcpStream;

const CONNECTION_STRING: &'static str = "127.0.0.1:8214";

pub fn imgui(not_charsel_or_loading: bool) {
if let Ok(mut stream) = TcpStream::connect(CONNECTION_STRING) {
let _ = stream.write(&[1, not_charsel_or_loading as u8]);
}
send_to_device([1, not_charsel_or_loading as u8].to_vec());
}

pub fn combat(
Expand All @@ -22,3 +17,20 @@ pub fn combat(
) {
combat::cbt(ev, src, dst, skillname, id, revision);
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn loop_imgui() {
crate::device::gen_device();
let sleep = std::time::Duration::from_millis(500);
let mut param = false;
loop {
imgui(param);
param = !param;
std::thread::sleep(sleep);
}
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
mod arcdps;
mod device;
mod exports;

use winapi::shared::minwindef::LPVOID;

fn main() -> LPVOID {
device::gen_device();
arcdps::gen_arcdps()
}

Expand Down

0 comments on commit 3318dc0

Please sign in to comment.