Compare commits

..

No commits in common. "dev" and "master" have entirely different histories.
dev ... master

118 changed files with 113 additions and 357 deletions

BIN
lo

Binary file not shown.

BIN
new.log

Binary file not shown.

18
rust/Cargo.lock generated
View file

@ -17,24 +17,24 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.68" version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.10" version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" checksum = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.3" version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -69,9 +69,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.17" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03" checksum = "123bd9499cfb380418d509322d7a6d52e5315f064fe4b3ad18a53d6b92c07859"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -79,7 +79,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "tf2p-network" name = "tf2p"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"flume", "flume",

View file

@ -1,5 +1,5 @@
[package] [package]
name = "tf2p-network" name = "tf2p"
version = "0.1.0" version = "0.1.0"
authors = ["TheLie0 <wf7za0XoHyYXVEkOeNu8>"] authors = ["TheLie0 <wf7za0XoHyYXVEkOeNu8>"]
edition = "2018" edition = "2018"

View file

@ -1,3 +0,0 @@
cargo build --all --all-targets --target=i686-unknown-linux-gnu &&
cp target/i686-unknown-linux-gnu/debug/libtf2p_network.so /mnt/disk3/TF2DS/tf/addons/sourcemod/extensions/tf2p-network.ext.so &&
/mnt/disk3/TF2DS/srcds_run +map ctf_2fort

View file

@ -1,29 +1,19 @@
use sm_ext::*; use sm_ext::{cell_t, register_natives, IExtension, IExtensionInterface, IShareSys, SMExtension, TryIntoPlugin, HandleError, HandleId, HandleType};
use std::thread; use std::thread;
use std::net::{SocketAddr, UdpSocket}; use std::net::{SocketAddr, UdpSocket};
use std::error::Error;
use std::collections::VecDeque;
use std::cell::RefCell; use std::cell::RefCell;
// use std::rc::Rc; Using Rc like it's in the example threw an Error
pub mod test; pub mod test;
pub mod socks;
mod socks; use sm_ext::{native, IPluginContext};
mod netman;
use std::ffi::CStr; use std::ffi::CStr;
use flume; use flume;
#[forwards]
struct Tf2pNetworkingForwards {
#[global_forward("OnConnectionRequest", ExecType::Single)]
on_con_req: fn(ip: &CStr) -> i32,
}
fn forward_wrapper(ip: &CStr) -> Result<i32, sm_ext::SPError> {
let result = Tf2pNetworkingForwards::on_con_req(|fwd| fwd.execute(ip))?;
Ok(result)
}
/// The network plugin entrypoint. /// The network plugin entrypoint.
#[native] #[native]
fn start_manager(_ctx: &IPluginContext, ip: &CStr, port1: i32) -> NMSender { fn start_manager(_ctx: &IPluginContext, ip: &CStr, port1: i32) -> NMSender {
@ -58,14 +48,103 @@ fn start_manager(_ctx: &IPluginContext, ip: &CStr, port1: i32) -> NMSender {
// Spawn manager thread // Spawn manager thread
thread::spawn(move || { thread::spawn(move || {
netman::manager(rx_s2m, tx_m2s, forward_wrapper, serv).unwrap(); manager(rx_c, rx_s2m, tx_m2s, serv).unwrap();
}); });
NMSender::new(tx_c) NMSender::new(tx_c)
} }
struct NMSender(flume::Sender<netman::NMMessage>); /// The network manager function.
/// It handles the incoming requests and sends the corresponding answers
fn manager<'a> (controller: flume::Receiver<NMCommand>, input: flume::Receiver<(Vec<u8>, SocketAddr)>, output: flume::Sender<(Vec<u8>, SocketAddr)>, serv_addr: SocketAddr) -> Result<(), Box<dyn Error>> {
let mut cl_ip: Option<SocketAddr> = None;
let mut addr_queue = VecDeque::new();
let conns: [Option<SocketAddr>; 3];
// This is the String "Source Engine Query" in binary form
let cliet_query = vec!(0xff, 0xff, 0xff, 0xff, 0x54, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00);
'main: loop {
// Get game info for cache
output.send((cliet_query.clone(), serv_addr)).unwrap();
let game_info = match input.recv() {
Ok((buf, src)) => {
let search = serv_addr.port().to_le_bytes();
let replace = (27419 as u16).to_le_bytes();
if src == serv_addr {
let mut buf = buf;
for i in 0..buf.len()-1 {
if buf[i..i+2] == search {
buf[i] = replace[0];
buf[i+1] = replace[1];
}
}
buf
} else {
panic!("Expected query answer from server, got message from {:?}", src);
}
}
Err(e) => panic!(e),
};
// Send cached game info on query and pass any other request to server
'inner1: loop {
//check for controller input
//TODO: rewrite this so it doesn't block
match controller.recv() {
Ok(comm) => {
match comm {
NMCommand::Kill => break 'main,
_ => (),
}
}
Err(e) => panic!(e),
}
match input.recv() {
Ok((buf, source)) => {
if source == serv_addr {
match addr_queue.pop_front() {
Some(ip) => {
output.send((buf.clone(), ip)).unwrap();
}
None => println!("No clients in queue."),
}
}else {
if buf[0 .. cliet_query.len()] == cliet_query[..] {
output.send((game_info.clone(), source)).unwrap();
}else {
output.send((buf.clone(), serv_addr)).unwrap();
addr_queue.push_back(source);
}
}
}
Err(e) => panic!(e),
}
}
//TODO: Get game info again
//TODO: Actual p2p communication
}
Ok(())
}
enum NMCommand{
Connect(u8, SocketAddr),
Kill
}
struct NMSender(flume::Sender<NMCommand>);
impl<'ctx> TryIntoPlugin<'ctx> for NMSender { impl<'ctx> TryIntoPlugin<'ctx> for NMSender {
type Error = HandleError; type Error = HandleError;
@ -80,7 +159,7 @@ impl<'ctx> TryIntoPlugin<'ctx> for NMSender {
impl NMSender { impl NMSender {
fn new(s: flume::Sender<netman::NMMessage>) -> Self { fn new(s: flume::Sender<NMCommand>) -> Self {
Self(s) Self(s)
} }
@ -95,12 +174,7 @@ pub struct Tf2pNetworking{
impl Tf2pNetworking { impl Tf2pNetworking {
fn get() -> &'static Self { fn get() -> &'static Self {
EXTENSION_GLOBAL.with(|ext| unsafe { EXTENSION_GLOBAL.with(|ext| unsafe { &(*ext.borrow().unwrap()).delegate })
&(*(match *ext.borrow(){
Some(e) => e,
None => panic!("Couldn't find myself"),
})).delegate
})
} }
fn handle_type() -> &'static HandleType<RefCell<NMSender>> { fn handle_type() -> &'static HandleType<RefCell<NMSender>> {
@ -113,16 +187,6 @@ impl IExtensionInterface for Tf2pNetworking {
fn on_extension_load(&mut self, myself: IExtension, sys: IShareSys, late: bool) -> Result<(), Box<dyn std::error::Error>> { fn on_extension_load(&mut self, myself: IExtension, sys: IShareSys, late: bool) -> Result<(), Box<dyn std::error::Error>> {
println!(">>> TF2P loaded! me = {:?}, sys = {:?}, late = {:?}", myself, sys, late); println!(">>> TF2P loaded! me = {:?}, sys = {:?}, late = {:?}", myself, sys, late);
let handlesys: IHandleSys = sys.request_interface(&myself)?;
println!(">>> Got interface: {:?} v{:?}", handlesys.get_interface_name(), handlesys.get_interface_version());
self.handle_type = Some(handlesys.create_type("NMSender", myself.get_identity())?);
let forward_manager: IForwardManager = sys.request_interface(&myself)?;
println!(">>> Got interface: {:?} v{:?}", forward_manager.get_interface_name(), forward_manager.get_interface_version());
Tf2pNetworkingForwards::register(&forward_manager)?;
register_natives!( register_natives!(
&sys, &sys,
&myself, &myself,
@ -133,9 +197,4 @@ impl IExtensionInterface for Tf2pNetworking {
Ok(()) Ok(())
} }
fn on_extension_unload(&mut self) {
Tf2pNetworkingForwards::unregister();
}
} }

View file

@ -1,202 +0,0 @@
use std::net::SocketAddr;
use std::error::Error;
use std::collections::VecDeque;
use std::ffi::CStr;
// use crate::Tf2pNetworkingForwards;
use flume;
pub enum NMMessage{
Connect(u8, SocketAddr),
Ping(SocketAddr),
UDPMessage(Vec<u8>, SocketAddr),
Kill
}
fn check_if_in_peer_ips (cl_ip: SocketAddr, peer_ips: &[Option<SocketAddr>]) -> bool {
let mut answer = false;
for ip_opt in peer_ips {
match ip_opt {
Some(ip) => {
if ip.ip() == cl_ip.ip() {
answer == true;
}
}
_ => ()
}
}
return answer;
}
/// The network manager function.
/// It handles the incoming requests and sends the corresponding answers
pub fn manager<'a> (input: flume::Receiver<NMMessage>, output: flume::Sender<(Vec<u8>, SocketAddr)>, forward: fn(&CStr) -> Result<i32, sm_ext::SPError>, serv_addr: SocketAddr) -> Result<(), Box<dyn Error>> {
let mut cl_ip: Option<SocketAddr> = None;
let mut addr_queue = VecDeque::new();
let mut conns = [None, None, None];
// This is the String "Source Engine Query" in binary form
let cliet_query = vec!(0xff, 0xff, 0xff, 0xff, 0x54, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x20, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x20, 0x51, 0x75, 0x65, 0x72, 0x79, 0x00);
'main: loop {
// Get game info for cache
let mut game_info = None;
let search = serv_addr.port().to_le_bytes();
let replace = (27419 as u16).to_le_bytes();
output.send((cliet_query.clone(), serv_addr)).unwrap();
while game_info == None {
match input.recv() {
Ok(m) => {
match m {
NMMessage::UDPMessage(buf, src) => {
if src == serv_addr {
let buf = &mut *buf.clone();
for i in 0..buf.len()-1{
if buf[i..i+2] == search {
println!("Port replaced.");
buf[i] = replace[0];
buf[i+1] = replace[1];
}
}
game_info = Some(Vec::from(buf));
} else {
panic!("Expected query answer from server, got message from {:?}", src);
}
}
NMMessage::Kill => break 'main,
_ => ()
}
}
Err(e) => panic!(e),
}
};
// Send cached game info on query and pass any other request to server
// Break when player data has been received
let mut player_data = [None, None];
'inner1: loop {
match input.recv() {
Ok(m) => {
match m {
NMMessage::UDPMessage(buf, src) => {
if src == serv_addr {
match addr_queue.pop_front() {
Some(ip) => {
output.send((buf.clone(), ip)).unwrap();
}
None => println!("No clients in queue."),
}
}else {
if buf.len() <= cliet_query.len() && buf[..] == cliet_query[..buf.len()] ||
buf.len() > cliet_query.len() && buf[..cliet_query.len()] == cliet_query[..] {
output.send((game_info.clone().unwrap(), src)).unwrap();
}else if buf.len() >= 256 && buf[0..6] == [0xff, 0xff, 0xff, 0xff, 0x6b, 0x18] {
cl_ip = Some(src);
player_data[0] = Some(buf);
output.send((player_data[0].clone().unwrap(), serv_addr)).unwrap();
println!("Got player Data pt 1.");
// This loop is activated when a player starts sending theur data and
// breaks the outer loop when the transmission is complete.
'even_more_inner: loop {
match input.recv() {
Ok(m) => {
match m {
NMMessage::UDPMessage(buf, src) => {
if src == serv_addr {
output.send((buf.clone(), cl_ip.unwrap())).unwrap();
} else if src == cl_ip.unwrap() {
if buf.len() >= 256 {
player_data[1] = Some(buf);
output.send((player_data[1].clone().unwrap(), serv_addr)).unwrap();
println!("Got player Data pt 2.");
break 'even_more_inner;
}
}
},
NMMessage::Kill => break 'main,
_ => {},
}
},
Err(e) => panic!(e),
}
}
break 'inner1;
}else {
output.send((buf.clone(), serv_addr)).unwrap();
addr_queue.push_back(src);
}
}
},
NMMessage::Kill => break 'main,
_ => {},
}
},
Err(e) => panic!(e),
}
}
// Exchange game data with peers and send updates to client.
'inner2: loop {
match input.recv() {
Ok(m) => {
match m {
NMMessage::UDPMessage(buf, src) => {
if src == serv_addr { // from server?
output.send((buf, cl_ip.unwrap())); // send to client
} else if check_if_in_peer_ips(src, &conns) { // from peer?
// handle request (quit, peers, gameinfo)
// send to cliet port (forward)
} else { // else
if buf == "TF2P?".as_bytes() {// handshake
output.send((Vec::from("Hey Ho!".as_bytes()), src));
}
else if buf == "Connect?".as_bytes() {
match forward(CStr::from_bytes_with_nul(src.ip().to_string()[..].as_bytes())?) {
Ok(i) => {
if i < 3 {
conns[i as usize] = Some(src);
// 'Ack ServPort CliPort' -> src
output.send((Vec::from(format!("Ack {:05}", serv_addr.port()).as_bytes()), src));
} else {
output.send((Vec::from("No".as_bytes()), src));
}
},
_ => (),
}
}
else if buf == "".as_bytes() { // Ack, SPort
// add to list TODO: Check internal state of place and validity
output.send((Vec::from("QInfo?".as_bytes()), src));
}
}
},
NMMessage::Connect(i, addr) => {
// TODO: Create internal state to check place and validity
output.send((Vec::from("Connect?".as_bytes()), addr));
},
NMMessage::Ping(addr) => {
output.send((Vec::from("TF2P?".as_bytes()), addr));
}
NMMessage::Kill => break 'main,
}
}
Err(e) => panic!(e),
}
}
}
Ok(())
}

View file

@ -1,8 +1,6 @@
use std::net::{UdpSocket, SocketAddr}; use std::net::{UdpSocket, SocketAddr};
use std::error::Error; use std::error::Error;
use crate::netman::NMMessage;
use flume; use flume;
/// Sends buffer messages from a mpsc channel to an udp socket. /// Sends buffer messages from a mpsc channel to an udp socket.
@ -18,7 +16,7 @@ pub fn chan_to_usock(input: flume::Receiver<(Vec<u8>, SocketAddr)>, output: UdpS
} }
/// Sends buffer messages from an udp socket to a mpsc channel. /// Sends buffer messages from an udp socket to a mpsc channel.
pub fn usock_to_chan(input: UdpSocket, output: flume::Sender<NMMessage>) -> Result<(), Box<dyn Error>> { pub fn usock_to_chan(input: UdpSocket, output: flume::Sender<(Vec<u8>, SocketAddr)>) -> Result<(), Box<dyn Error>> {
let mut buf = [0; 2048]; let mut buf = [0; 2048];
let mut tup; let mut tup;
@ -27,12 +25,9 @@ pub fn usock_to_chan(input: UdpSocket, output: flume::Sender<NMMessage>) -> Resu
{ {
tup = input.recv_from(&mut buf).unwrap(); tup = input.recv_from(&mut buf).unwrap();
} }
match output.send(NMMessage::UDPMessage(buf[0..tup.0 + 1].to_vec(), tup.1)) { match output.send((buf[0..tup.0 + 1].to_vec(), tup.1)) {
Ok(s) => s, Ok(s) => s,
Err(e) => { Err(e) => panic!(e)
println!("Whoops");
panic!(e)
}
} }
} }
} }

6
tests/Cargo.lock generated
View file

@ -1,6 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "tests"
version = "0.1.0"

View file

@ -1,9 +0,0 @@
[package]
name = "tests"
version = "0.1.0"
authors = ["TheLie0 <wf7za0XoHyYXVEkOeNu8>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View file

@ -1,41 +0,0 @@
use std::env;
use std::net::{UdpSocket, SocketAddr};
fn main() {
println!("Hello, world!");
let args: Vec<String> = env::args().collect();
let mut server_adress = None;
for i in 0..args.len()-1 {
if args[i] == "-s" {
server_adress = Some(args[i + 1].parse::<SocketAddr>()
.expect("Unable to parse output socket address"));
}
}
let server_message = [0xff, 0xff, 0xff, 0xff, 0x41, 0x33, 0x49, 0x4f, 0x5a,
0x7c, 0x71, 0x34, 0x2d, 0xf9, 0x23, 0x30, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x08, 0xc0, 0x56, 0x25, 0x42, 0x38, 0x40, 0x01, 0x01, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x00];
let server_socket = UdpSocket::bind("127.0.0.1:27123")
.expect("Could not bind to 127.0.0.1:27123.");
// Connect to client port
match server_adress {
Some(a) => server_socket.connect(a).expect("Couldn't connect to server."),
None => panic!("No Server adress provided!")
}
server_socket.send(& server_message).expect("Send failed.");
// print all traffic from cl
loop{
let mut output = [0; 128];
server_socket.recv(&mut output).unwrap();
}
}

View file

@ -1 +0,0 @@
{"rustc_fingerprint":1683364760131821644,"outputs":{"1164083562126845933":["rustc 1.44.0 (49cae5576 2020-06-01)\nbinary: rustc\ncommit-hash: 49cae55760da0a43428eba73abcb659bb70cf2e4\ncommit-date: 2020-06-01\nhost: x86_64-unknown-linux-gnu\nrelease: 1.44.0\nLLVM version: 9.0\n",""],"4476964694761187371":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/dannieboy/.rustup/toolchains/stable-x86_64-unknown-linux-gnu\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_vendor=\"unknown\"\nunix\n",""]},"successes":{}}

View file

@ -1 +0,0 @@
{"rustc":5807094999684781751,"features":"[]","target":8443017735982037405,"profile":14891217944882224483,"path":1036222786711178230,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/tests-c066b971b0bbd15a/dep-bin-tests-c066b971b0bbd15a"}}],"rustflags":[],"metadata":7884812644471753209}

View file

@ -1 +0,0 @@
This file has an mtime of when this was started.

View file

@ -1 +0,0 @@
{"rustc":5807094999684781751,"features":"[]","target":8443017735982037405,"profile":14996655781355331481,"path":1036222786711178230,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/tests-e7efc60f064cff81/dep-bin-tests-e7efc60f064cff81"}}],"rustflags":[],"metadata":7884812644471753209}

View file

@ -1 +0,0 @@
This file has an mtime of when this was started.

View file

@ -1,5 +0,0 @@
/mnt/disk1/projects/TF2P/tests/target/debug/deps/tests-c066b971b0bbd15a.rmeta: src/main.rs
/mnt/disk1/projects/TF2P/tests/target/debug/deps/tests-c066b971b0bbd15a.d: src/main.rs
src/main.rs:

View file

@ -1,5 +0,0 @@
/mnt/disk1/projects/TF2P/tests/target/debug/deps/tests-e7efc60f064cff81: src/main.rs
/mnt/disk1/projects/TF2P/tests/target/debug/deps/tests-e7efc60f064cff81.d: src/main.rs
src/main.rs:

Binary file not shown.

View file

@ -1 +0,0 @@
/mnt/disk1/projects/TF2P/tests/target/debug/tests: /mnt/disk1/projects/TF2P/tests/src/main.rs

View file

@ -1 +0,0 @@
{"rustc_fingerprint":4567211532567258067,"outputs":{"1138116330425514636":["___\n",""],"4476964694761187371":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/dannieboy/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/rls\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"mmx\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"cas\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nunix\n",""],"1164083562126845933":["rustc 1.39.0-nightly (c6e9c76c5 2019-09-04)\nbinary: rustc\ncommit-hash: c6e9c76c59e3c10acd63ca9ec157a8894ea1a068\ncommit-date: 2019-09-04\nhost: x86_64-unknown-linux-gnu\nrelease: 1.39.0-nightly\nLLVM version: 9.0\n",""],"2196823701345282402":["___\nlib___.rlib\nlib___.so\nlib___.so\nlib___.a\nlib___.so\n/home/dannieboy/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/rls\ndebug_assertions\nproc_macro\ntarget_arch=\"x86_64\"\ntarget_endian=\"little\"\ntarget_env=\"gnu\"\ntarget_family=\"unix\"\ntarget_feature=\"fxsr\"\ntarget_feature=\"mmx\"\ntarget_feature=\"sse\"\ntarget_feature=\"sse2\"\ntarget_has_atomic=\"16\"\ntarget_has_atomic=\"32\"\ntarget_has_atomic=\"64\"\ntarget_has_atomic=\"8\"\ntarget_has_atomic=\"cas\"\ntarget_has_atomic=\"ptr\"\ntarget_os=\"linux\"\ntarget_pointer_width=\"64\"\ntarget_thread_local\ntarget_vendor=\"unknown\"\nunix\n",""]},"successes":{}}

View file

@ -1 +0,0 @@
{"rustc":14587545897571530554,"features":"[]","target":8443017735982037405,"profile":14891217944882224483,"path":1036222786711178230,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug/.fingerprint/tests-2d2ee19b1caaa0fc/dep-bin-tests-2d2ee19b1caaa0fc"}}],"rustflags":[],"metadata":7884812644471753209}

View file

@ -1 +0,0 @@
This file has an mtime of when this was started.

Some files were not shown because too many files have changed in this diff Show more