Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8393ad3656 | |||
| dca2900263 | |||
| 9b2287a3f0 | |||
| e6520d99ec | |||
| 40cdec017c | |||
| a8fdbeb025 |
5 changed files with 110 additions and 24 deletions
|
|
@ -341,3 +341,33 @@ jobs:
|
||||||
CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }}
|
CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }}
|
||||||
DATABASE_URL: ${{ secrets.DATABASE_SMM }}
|
DATABASE_URL: ${{ secrets.DATABASE_SMM }}
|
||||||
run: ./.ci-scripts/make-edition.sh super-mario-maker
|
run: ./.ci-scripts/make-edition.sh super-mario-maker
|
||||||
|
|
||||||
|
terraria:
|
||||||
|
runs-on: debian-trixie
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v7
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Cache container storage
|
||||||
|
uses: actions/cache@v6
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
/var/lib/containers/storage
|
||||||
|
/run/containers/storage
|
||||||
|
~/.local/share/containers/storage
|
||||||
|
key: image-cache
|
||||||
|
|
||||||
|
- name: Login to registry
|
||||||
|
run: docker login -u ${{ secrets.PACKAGE_USER }} -p ${{ secrets.PACKAGE_PWD }} git.spbr.net
|
||||||
|
|
||||||
|
- name: Set short SHA
|
||||||
|
run: echo "SHORT_SHA=${GITHUB_SHA::6}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Build Terraria edition
|
||||||
|
env:
|
||||||
|
CI_REGISTRY_IMAGE: git.spbr.net/spacebar/rust-nex
|
||||||
|
CI_COMMIT_SHORT_SHA: ${{ env.SHORT_SHA }}
|
||||||
|
run: ./.ci-scripts/make-edition.sh terraria
|
||||||
|
|
|
||||||
|
|
@ -138,3 +138,15 @@ super-mario-maker:
|
||||||
RNEX_VIRTUAL_PORT_SECURE: "1:10"
|
RNEX_VIRTUAL_PORT_SECURE: "1:10"
|
||||||
RNEX_DEFAULT_PORT: 6000
|
RNEX_DEFAULT_PORT: 6000
|
||||||
RNEX_ACCESS_KEY: "9f2b4678"
|
RNEX_ACCESS_KEY: "9f2b4678"
|
||||||
|
terraria:
|
||||||
|
include-in-checkall: true
|
||||||
|
features:
|
||||||
|
- prudpv1
|
||||||
|
- third-notif-param
|
||||||
|
- v3-8-15
|
||||||
|
settings:
|
||||||
|
AUTH_REPORT_VERSION: "branch:origin/release/ngs/3.8.x.200x build:3_8_13_2004_0"
|
||||||
|
RNEX_VIRTUAL_PORT_INSECURE: "1:10"
|
||||||
|
RNEX_VIRTUAL_PORT_SECURE: "1:10"
|
||||||
|
RNEX_DEFAULT_PORT: 10000
|
||||||
|
RNEX_ACCESS_KEY: "3d37fbdb"
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ pub struct InternalConnection<C: CryptoInstance> {
|
||||||
server_packet_counter: u16,
|
server_packet_counter: u16,
|
||||||
client_packet_counter: u16,
|
client_packet_counter: u16,
|
||||||
unacknowledged_packets: HashMap<u16, Arc<Vec<u8>>>,
|
unacknowledged_packets: HashMap<u16, Arc<Vec<u8>>>,
|
||||||
|
packet_buffer: Vec<u8>,
|
||||||
packet_queue: HashMap<u16, (Instant, PRUDPV0Packet<Vec<u8>>)>,
|
packet_queue: HashMap<u16, (Instant, PRUDPV0Packet<Vec<u8>>)>,
|
||||||
}
|
}
|
||||||
pub struct Connection<C: CryptoInstance> {
|
pub struct Connection<C: CryptoInstance> {
|
||||||
|
|
@ -96,7 +97,7 @@ impl<C: Crypto> Server<C> {
|
||||||
.expect("packet malformed in creation"),
|
.expect("packet malformed in creation"),
|
||||||
);*/
|
);*/
|
||||||
let mut inner = conn.inner.lock().await;
|
let mut inner = conn.inner.lock().await;
|
||||||
let pieces = data.chunks(700);
|
let pieces = data.chunks(962);
|
||||||
let max_piece = pieces.len() - 1;
|
let max_piece = pieces.len() - 1;
|
||||||
let mut frag_num = 1;
|
let mut frag_num = 1;
|
||||||
for (i, piece) in pieces.enumerate() {
|
for (i, piece) in pieces.enumerate() {
|
||||||
|
|
@ -140,9 +141,18 @@ impl<C: Crypto> Server<C> {
|
||||||
.send_to(&data, conn.addr.regular_socket_addr)
|
.send_to(&data, conn.addr.regular_socket_addr)
|
||||||
.await
|
.await
|
||||||
.ok();
|
.ok();
|
||||||
|
sleep(Duration::from_millis(500)).await;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
println!("connection exceeded max fail count, disconnecting");
|
||||||
|
let Some(conn) = conn.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(this) = this.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let mut conns = this.connections.write().await;
|
||||||
|
conns.remove(&(conn.addr, conn.session_id));
|
||||||
|
drop(conns);
|
||||||
});
|
});
|
||||||
frag_num += 1;
|
frag_num += 1;
|
||||||
}
|
}
|
||||||
|
|
@ -282,6 +292,7 @@ impl<C: Crypto> Server<C> {
|
||||||
server_packet_counter: 1,
|
server_packet_counter: 1,
|
||||||
unacknowledged_packets: HashMap::new(),
|
unacknowledged_packets: HashMap::new(),
|
||||||
packet_queue: HashMap::new(),
|
packet_queue: HashMap::new(),
|
||||||
|
packet_buffer: vec![],
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -334,6 +345,13 @@ impl<C: Crypto> Server<C> {
|
||||||
warn!("data packet on inactive connection from: {:?}", addr);
|
warn!("data packet on inactive connection from: {:?}", addr);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if header.type_flags.get_flags() & ACK != 0 {
|
||||||
|
let mut inner = res.inner.lock().await;
|
||||||
|
inner.unacknowledged_packets.remove(&header.sequence_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
info!("frag: {}", frag_id);
|
info!("frag: {}", frag_id);
|
||||||
let mut conn = res.inner.lock().await;
|
let mut conn = res.inner.lock().await;
|
||||||
let ack = new_data_packet(
|
let ack = new_data_packet(
|
||||||
|
|
@ -368,9 +386,16 @@ impl<C: Crypto> Server<C> {
|
||||||
};
|
};
|
||||||
|
|
||||||
conn.crypto_instance.decrypt_incoming(payload);
|
conn.crypto_instance.decrypt_incoming(payload);
|
||||||
|
conn.packet_buffer.extend_from_slice(payload);
|
||||||
res.target.send(payload.to_owned()).await;
|
|
||||||
conn.client_packet_counter += 1;
|
conn.client_packet_counter += 1;
|
||||||
|
if *packet.fragment_id().unwrap() != 0 {
|
||||||
|
info!("handeling fragmented packet");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.target
|
||||||
|
.send(std::mem::take(&mut conn.packet_buffer))
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
info!("finished handeling packets, dropping inner connection");
|
info!("finished handeling packets, dropping inner connection");
|
||||||
drop(conn);
|
drop(conn);
|
||||||
|
|
@ -472,8 +497,8 @@ impl<C: Crypto> Server<C> {
|
||||||
inner.last_action = Instant::now();
|
inner.last_action = Instant::now();
|
||||||
drop(inner);
|
drop(inner);
|
||||||
};
|
};
|
||||||
if header.type_flags.get_flags() & ACK != 0 {
|
if header.type_flags.get_flags() & ACK != 0 && header.type_flags.get_types() != DATA {
|
||||||
info!("got ack(acks are ignored for now)");
|
info!("got ack(acks are ignored for now(unless they are data acks))");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
println!("{:?}", header);
|
println!("{:?}", header);
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ struct InternalConnection<E: CryptoHandlerConnectionInstance> {
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
packet_queue: HashMap<u16, PRUDPV1Packet>,
|
packet_queue: HashMap<u16, PRUDPV1Packet>,
|
||||||
last_packet_time: Instant,
|
last_packet_time: Instant,
|
||||||
|
partial_packet: Vec<u8>,
|
||||||
unacknowleged_packets: Vec<(Instant, PRUDPV1Packet)>,
|
unacknowleged_packets: Vec<(Instant, PRUDPV1Packet)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -431,6 +432,7 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
packet_queue: Default::default(),
|
packet_queue: Default::default(),
|
||||||
last_packet_time: Instant::now(),
|
last_packet_time: Instant::now(),
|
||||||
unacknowleged_packets: Vec::new(),
|
unacknowleged_packets: Vec::new(),
|
||||||
|
partial_packet: Vec::new(),
|
||||||
supported_function_version,
|
supported_function_version,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -573,11 +575,24 @@ impl<T: CryptoHandler> InternalSocket<T> {
|
||||||
while let Some(mut packet) = conn.packet_queue.remove(&counter) {
|
while let Some(mut packet) = conn.packet_queue.remove(&counter) {
|
||||||
conn.crypto_handler_instance
|
conn.crypto_handler_instance
|
||||||
.decrypt_incoming(packet.header.substream_id, &mut packet.payload[..]);
|
.decrypt_incoming(packet.header.substream_id, &mut packet.payload[..]);
|
||||||
|
conn.partial_packet
|
||||||
conn.data_sender.send(packet.payload).await.ok();
|
.extend_from_slice(&mut packet.payload[..]);
|
||||||
|
|
||||||
conn.reliable_client_counter = conn.reliable_client_counter.overflowing_add(1).0;
|
conn.reliable_client_counter = conn.reliable_client_counter.overflowing_add(1).0;
|
||||||
counter = conn.reliable_client_counter;
|
counter = conn.reliable_client_counter;
|
||||||
|
if packet.options.iter().any(|v| {
|
||||||
|
if let FragmentId(f) = v {
|
||||||
|
*f != 0
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
println!("handeling fragmented packet");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let packet = std::mem::take(&mut conn.partial_packet);
|
||||||
|
|
||||||
|
conn.data_sender.send(packet).await.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -690,19 +705,7 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
||||||
let conn = &**conn;
|
let conn = &**conn;
|
||||||
let mut conn = conn.lock().await;
|
let mut conn = conn.lock().await;
|
||||||
|
|
||||||
if conn.supported_function_version == 1 {
|
if packet.header.substream_id == 1 {
|
||||||
let mut collected_ids: Vec<u16> = Vec::new();
|
|
||||||
let mut cursor = Cursor::new(&packet.payload);
|
|
||||||
|
|
||||||
while let Ok(v) = read_u16(&mut cursor) {
|
|
||||||
collected_ids.push(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.unacknowleged_packets.retain_mut(|(_, up)| {
|
|
||||||
!(collected_ids.iter().any(|id| up.header.sequence_id == *id)
|
|
||||||
|| up.header.sequence_id <= packet.header.sequence_id)
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
let mut collected_ids: Vec<u16> = Vec::new();
|
let mut collected_ids: Vec<u16> = Vec::new();
|
||||||
let mut cursor = Cursor::new(&packet.payload);
|
let mut cursor = Cursor::new(&packet.payload);
|
||||||
|
|
||||||
|
|
@ -729,10 +732,22 @@ impl<T: CryptoHandler> AnyInternalSocket for InternalSocket<T> {
|
||||||
collected_ids.push(additional_sequence_id);
|
collected_ids.push(additional_sequence_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.unacknowleged_packets.retain_mut(|(_, up)| {
|
conn.unacknowleged_packets.retain(|(_, up)| {
|
||||||
!(collected_ids.iter().any(|id| up.header.sequence_id == *id)
|
!(collected_ids.iter().any(|id| up.header.sequence_id == *id)
|
||||||
|| up.header.sequence_id <= sequence_id)
|
|| up.header.sequence_id <= sequence_id)
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
let mut collected_ids: Vec<u16> = Vec::new();
|
||||||
|
let mut cursor = Cursor::new(&packet.payload);
|
||||||
|
|
||||||
|
while let Ok(v) = read_u16(&mut cursor) {
|
||||||
|
collected_ids.push(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.unacknowleged_packets.retain(|(_, up)| {
|
||||||
|
!(collected_ids.iter().any(|id| up.header.sequence_id == *id)
|
||||||
|
|| up.header.sequence_id <= packet.header.sequence_id)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!("non connection acknowledgement packet on nonexistent connection...")
|
error!("non connection acknowledgement packet on nonexistent connection...")
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,10 @@ impl TryFrom<&str> for StationUrl {
|
||||||
fn try_from(value: &str) -> Result<Self, ()> {
|
fn try_from(value: &str) -> Result<Self, ()> {
|
||||||
let (url_type, options) = value.split_at(value.find(":/").ok_or(())?);
|
let (url_type, options) = value.split_at(value.find(":/").ok_or(())?);
|
||||||
|
|
||||||
|
if value.len() >= 1024 {
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
let options = &options[2..];
|
let options = &options[2..];
|
||||||
|
|
||||||
let url_type = match url_type {
|
let url_type = match url_type {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue