Skip to content

Commit 82b436b

Browse files
committed
yay!
1 parent b62b4eb commit 82b436b

File tree

6 files changed

+71
-28
lines changed

6 files changed

+71
-28
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
mv target/i686-pc-windows-msvc/release/fix_damage_to_offside_ship_artillery.dll ./mods/
1919
mv target/i686-pc-windows-msvc/release/fix_invulnerable_ship_artillery_slots.dll ./mods/
2020
mv target/i686-pc-windows-msvc/release/fix_market_hall_production_town.dll ./mods/
21+
mv target/i686-pc-windows-msvc/release/fix_multiplayer_locks.dll ./mods/
2122
mv target/i686-pc-windows-msvc/release/fix_new_settlement_ware_production.dll ./mods/
2223
mv target/i686-pc-windows-msvc/release/fix_siege_beggar_satisfaction_bonus.dll ./mods/
2324
mv target/i686-pc-windows-msvc/release/high_res.dll ./mods/

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ log = "0.4"
4040
sysinfo = "0.29"
4141
win_dbg_logger = "0.1"
4242
num-traits = "0.2"
43-
num-derive = "0.3"
43+
num-derive = "0.4"

mod-fix-multiplayer-locks/src/ffi.rs

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use std::{backtrace::Backtrace, ffi::c_void, thread};
1+
use std::{ffi::c_void, thread};
22

33
use hooklet::windows::x86::{deploy_rel32_raw, replace_slice_rwx, X86Rel32Type};
4-
use log::{debug, error, trace};
4+
use log::{debug, trace};
55
use p3_api::{mods::init_mod, operations::OperationsPtr};
66

77
#[no_mangle]
@@ -56,52 +56,60 @@ pub unsafe extern "C" fn start() -> u32 {
5656
debug!("Fix operations_network_host_send_to_all_and_move_to_current_ops current lock");
5757
match deploy_rel32_raw(0x0054BCCB, &lock_current_clean as *const c_void as _, X86Rel32Type::Call) {
5858
Ok(_) => {}
59-
Err(_) => return 11,
59+
Err(_) => return 9,
6060
}
6161
let operations_network_host_send_to_all_and_move_to_current_ops_lock: [u8; 5] = [0x90, 0x90, 0x90, 0x90, 0x90];
6262
match replace_slice_rwx(0x0054BCCB + 5, &operations_network_host_send_to_all_and_move_to_current_ops_lock) {
6363
Ok(_) => {}
64-
Err(_) => return 12,
64+
Err(_) => return 10,
6565
}
6666

6767
debug!("Fix operations_network_host_send_to_all_and_move_to_current_ops current unlock");
6868
match deploy_rel32_raw(0x0054BD2C, &unlock_current_clean as *const c_void as _, X86Rel32Type::Call) {
6969
Ok(_) => {}
70-
Err(_) => return 13,
70+
Err(_) => return 11,
7171
}
7272
match replace_slice_rwx(0x0054BD2C + 5, &[0x90]) {
7373
Ok(_) => {}
74-
Err(_) => return 14,
74+
Err(_) => return 12,
7575
}
7676

7777
debug!("Fix operations_network_host_receive_from_all_and_own_pending pending lock");
7878
// There is a callee saved register restoring `pop ebx`` in the lock code (╯°□°)╯︵ ┻━┻
7979
match deploy_rel32_raw(0x0054B90D, &lock_pending_clean as *const c_void as _, X86Rel32Type::Call) {
8080
Ok(_) => {}
81-
Err(_) => return 15,
81+
Err(_) => return 13,
8282
}
8383
match deploy_rel32_raw(0x0054B90D + 5, 0x0054B932, X86Rel32Type::Jump) {
8484
Ok(_) => {}
85-
Err(_) => return 16,
85+
Err(_) => return 14,
8686
}
8787

8888
debug!("Fix operations_network_host_receive_from_all_and_own_pending pending unlock");
8989
match deploy_rel32_raw(0x0054B949, &unlock_pending_clean as *const c_void as _, X86Rel32Type::Call) {
9090
Ok(_) => {}
91-
Err(_) => return 17,
91+
Err(_) => return 15,
9292
}
9393
// We sneak in the `pop ebx` here to keep the stack intact 🧠
9494
match replace_slice_rwx(0x0054B949 + 5, &[0x5b, 0x90, 0x90, 0x90, 0x90]) {
9595
Ok(_) => {}
96-
Err(_) => return 18,
96+
Err(_) => return 16,
9797
}
9898

9999
debug!("Fix operations_client_receive_from_host current lock");
100100
match deploy_rel32_raw(0x0054B13F, &try_lock_current_clean as *const c_void as _, X86Rel32Type::Call) {
101101
Ok(_) => {}
102-
Err(_) => return 19,
102+
Err(_) => return 17,
103103
}
104104
match replace_slice_rwx(0x0054B13F + 5, &[0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90]) {
105+
Ok(_) => {}
106+
Err(_) => return 18,
107+
}
108+
match deploy_rel32_raw(0x0054B200, &try_lock_current_clean as *const c_void as _, X86Rel32Type::Call) {
109+
Ok(_) => {}
110+
Err(_) => return 19,
111+
}
112+
match replace_slice_rwx(0x0054B200 + 5, &[0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90]) {
105113
Ok(_) => {}
106114
Err(_) => return 20,
107115
}
@@ -120,28 +128,64 @@ pub unsafe extern "C" fn start() -> u32 {
120128
Ok(_) => {}
121129
Err(_) => return 23,
122130
}
131+
match deploy_rel32_raw(0x0054B21C, &unlock_current_clean as *const c_void as _, X86Rel32Type::Call) {
132+
Ok(_) => {}
133+
Err(_) => return 24,
134+
}
135+
match replace_slice_rwx(0x0054B21C + 5, &[0x90]) {
136+
Ok(_) => {}
137+
Err(_) => return 25,
138+
}
139+
// Fix jnz above
140+
match replace_slice_rwx(0x0054B20E + 1, &[0x12]) {
141+
Ok(_) => {}
142+
Err(_) => return 26,
143+
}
123144

124145
debug!("Fix operations_network_client_send_pending_operations pending lock");
146+
match deploy_rel32_raw(0x0054AFB7, &lock_pending_clean as *const c_void as _, X86Rel32Type::Call) {
147+
Ok(_) => {}
148+
Err(_) => return 27,
149+
}
150+
match deploy_rel32_raw(0x0054AFB7 + 5, 0x0054AFD3, X86Rel32Type::Jump) {
151+
Ok(_) => {}
152+
Err(_) => return 28,
153+
}
154+
125155
debug!("Fix operations_network_client_send_pending_operations pending unlock");
126-
let addr: u32 = &try_lock_current_clean as *const _ as _;
127-
debug!("#### {addr}");
156+
match deploy_rel32_raw(0x0054B049, &unlock_pending_clean as *const c_void as _, X86Rel32Type::Call) {
157+
Ok(_) => {}
158+
Err(_) => return 29,
159+
}
160+
match deploy_rel32_raw(0x0054B063, &unlock_pending_clean as *const c_void as _, X86Rel32Type::Call) {
161+
Ok(_) => {}
162+
Err(_) => return 30,
163+
}
164+
match replace_slice_rwx(0x0054B049 + 5, &[0x90]) {
165+
Ok(_) => {}
166+
Err(_) => return 31,
167+
}
168+
match replace_slice_rwx(0x0054B063 + 5, &[0x90]) {
169+
Ok(_) => {}
170+
Err(_) => return 32,
171+
}
128172

129173
0
130174
}
131175

132176
#[no_mangle]
133177
unsafe extern "stdcall" fn lock_pending() {
134178
let thread_id = thread::current().id();
135-
debug!("lock_pending {thread_id:?}");
179+
trace!("lock_pending {thread_id:?}");
136180
crate::lock(&crate::PENDING_OPS_LOCK);
137181
}
138182

139183
#[no_mangle]
140184
unsafe extern "stdcall" fn try_lock_pending() -> u32 {
141185
let thread_id = thread::current().id();
142-
debug!("try_lock_pending {thread_id:?}");
186+
trace!("try_lock_pending {thread_id:?}");
143187
let in_use = crate::try_lock(&crate::PENDING_OPS_LOCK);
144-
debug!("try_lock_pending {thread_id:?} {in_use}");
188+
trace!("try_lock_pending {thread_id:?} {in_use}");
145189
in_use
146190
}
147191

@@ -151,7 +195,7 @@ unsafe extern "stdcall" fn unlock_pending() {
151195
// Unlock ops are often not guarded by the mp check, so we have to do an mp check here.
152196
if operations.get_status() & 0x0c != 0 {
153197
let thread_id = thread::current().id();
154-
debug!("unlock_pending {thread_id:?}");
198+
trace!("unlock_pending {thread_id:?}");
155199
crate::unlock(&crate::PENDING_OPS_LOCK);
156200
} else {
157201
crate::PENDING_OPS_LOCK.store(0, std::sync::atomic::Ordering::SeqCst);
@@ -161,16 +205,16 @@ unsafe extern "stdcall" fn unlock_pending() {
161205
#[no_mangle]
162206
unsafe extern "stdcall" fn lock_current() {
163207
let thread_id = thread::current().id();
164-
debug!("lock_current {thread_id:?}");
208+
trace!("lock_current {thread_id:?}");
165209
crate::lock(&crate::CURRENT_OPS_LOCK);
166210
}
167211

168212
#[no_mangle]
169213
unsafe extern "stdcall" fn try_lock_current() -> u32 {
170214
let thread_id = thread::current().id();
171-
debug!("try_lock_current {thread_id:?}");
215+
trace!("try_lock_current {thread_id:?}");
172216
let in_use = crate::try_lock(&crate::CURRENT_OPS_LOCK);
173-
debug!("try_lock_current {thread_id:?} {in_use}");
217+
trace!("try_lock_current {thread_id:?} {in_use}");
174218
in_use
175219
}
176220

@@ -180,7 +224,7 @@ unsafe extern "stdcall" fn unlock_current() {
180224
// Unlock ops are often not guarded by the mp check, so we have to do an mp check here.
181225
if operations.get_status() & 0x0c != 0 {
182226
let thread_id = thread::current().id();
183-
debug!("unlock_current {thread_id:?}");
227+
trace!("unlock_current {thread_id:?}");
184228
crate::unlock(&crate::CURRENT_OPS_LOCK);
185229
} else {
186230
crate::CURRENT_OPS_LOCK.store(0, std::sync::atomic::Ordering::SeqCst);

mod-fix-multiplayer-locks/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ pub(crate) fn lock(lock: &AtomicU16) {
1616
pub(crate) fn try_lock(lock: &AtomicU16) -> u32 {
1717
match lock.compare_exchange(0, 1, Ordering::SeqCst, Ordering::SeqCst) {
1818
Ok(_) => 0,
19-
Err(_) => 1
19+
Err(_) => 1,
2020
}
2121
}
2222

2323
pub(crate) fn unlock(lock: &AtomicU16) {
2424
let old = lock.swap(0, Ordering::SeqCst);
2525
if old != 1 {
26-
panic!("Lock is dirty ({old})");
26+
panic!("Cannot unlock, lock is dirty ({old})");
2727
}
2828
}

p3-agent/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ log = "0.4"
1212
toml = "0.7"
1313
win_dbg_logger = "0.1"
1414
serde = { version = "1.0", features = ["derive"] }
15-
num-traits = "0.2"
16-
num-derive = "0.3"
1715

1816
[dependencies.windows]
1917
version = "0.48"

p3-api/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ crate-type = ["cdylib", "rlib"]
99

1010
[dependencies]
1111
log = "0.4"
12-
num-traits = "0.2"
13-
num-derive = "0.3"
12+
num-traits = { workspace = true }
13+
num-derive = { workspace = true }
1414
strum = { version = "0.24", features = ["derive"] }
1515
csbindgen = { version = "1.7.0", optional = true }
1616
win_dbg_logger = { workspace = true }

0 commit comments

Comments
 (0)