1#![allow(non_camel_case_types)]
4
5use unity::{IntPtr, MethodInfo};
6
7fn method_info_intptr(callback_ptr: *mut u8, args: u8) -> IntPtr {
8 let mi = unity::method_info_for_fn(callback_ptr, args);
9 IntPtr(mi as *const MethodInfo as *mut ())
10}
11
12#[cfg(feature = "system-collections-generic-list_1")]
13mod list_1_ext {
14 use crate::system::collections::generic::list_1::{IList_1Methods, List_1};
15
16 pub trait List_1Ext<T: Copy + ::unity::ClassIdentity> {
17 fn with_capacity(capacity: i32) -> Self;
18 fn get(self, index: i32) -> T;
19 fn iter(self) -> List_1Iter<T>;
20 fn count(self) -> i32;
21 }
22
23 impl<T: Copy + ::unity::ClassIdentity> List_1Ext<T> for List_1<T> {
24 fn with_capacity(capacity: i32) -> Self {
25 let list = Self::new();
26 list.ensure_capacity(capacity);
27 list
28 }
29
30 fn get(self, index: i32) -> T {
31 self.get_item(index)
32 }
33
34 fn iter(self) -> List_1Iter<T> {
35 let len = self.get_count();
36 List_1Iter { list: self, index: 0, len }
37 }
38
39 fn count(self) -> i32 {
40 self.get_count()
41 }
42 }
43
44 pub struct List_1Iter<T: Copy + ::unity::ClassIdentity> {
45 list: List_1<T>,
46 index: i32,
47 len: i32,
48 }
49
50 impl<T: Copy + ::unity::ClassIdentity> Iterator for List_1Iter<T> {
51 type Item = T;
52
53 fn next(&mut self) -> Option<T> {
54 if self.index < self.len {
55 let v = self.list.get_item(self.index);
56 self.index += 1;
57 Some(v)
58 } else {
59 None
60 }
61 }
62
63 fn size_hint(&self) -> (usize, Option<usize>) {
64 let r = (self.len - self.index) as usize;
65 (r, Some(r))
66 }
67 }
68
69 impl<T: Copy + ::unity::ClassIdentity> ExactSizeIterator for List_1Iter<T> {}
70}
71#[cfg(feature = "system-collections-generic-list_1")]
72pub use list_1_ext::*;
73
74#[cfg(feature = "system-collections-generic-dictionary_2")]
75mod dictionary_2_ext {
76 use ::unity::Array;
77
78 use crate::system::collections::generic::dictionary_2::{
79 Dictionary_2, IDictionary_2Methods, IDictionary_2_KeyCollectionMethods, IDictionary_2_ValueCollectionMethods,
80 };
81
82 pub trait Dictionary_2Ext<K: Copy + ::unity::ClassIdentity, V: Copy + ::unity::ClassIdentity> {
83 fn iter(self) -> Dictionary_2Iter<K, V>;
84 }
85
86 impl<K: Copy + ::unity::ClassIdentity, V: Copy + ::unity::ClassIdentity> Dictionary_2Ext<K, V> for Dictionary_2<K, V> {
87 fn iter(self) -> Dictionary_2Iter<K, V> {
88 let len = self.get_count();
89 let keys = Array::<K>::of_len(len as usize).expect("Dictionary_2Iter: keys alloc");
90 let values = Array::<V>::of_len(len as usize).expect("Dictionary_2Iter: values alloc");
91 self.get_keys().copy_to(keys, 0);
92 self.get_values().copy_to(values, 0);
93 Dictionary_2Iter { keys, values, index: 0, len }
94 }
95 }
96
97 pub struct Dictionary_2Iter<K: Copy + ::unity::ClassIdentity, V: Copy + ::unity::ClassIdentity> {
98 keys: Array<K>,
99 values: Array<V>,
100 index: i32,
101 len: i32,
102 }
103
104 impl<K: Copy + ::unity::ClassIdentity, V: Copy + ::unity::ClassIdentity> Iterator for Dictionary_2Iter<K, V> {
105 type Item = (K, V);
106
107 fn next(&mut self) -> Option<(K, V)> {
108 if self.index >= self.len {
109 return None;
110 }
111 let i = self.index as usize;
112 let pair = (self.keys.get(i), self.values.get(i));
113 self.index += 1;
114 Some(pair)
115 }
116
117 fn size_hint(&self) -> (usize, Option<usize>) {
118 let r = (self.len - self.index) as usize;
119 (r, Some(r))
120 }
121 }
122
123 impl<K: Copy + ::unity::ClassIdentity, V: Copy + ::unity::ClassIdentity> ExactSizeIterator for Dictionary_2Iter<K, V> {}
124}
125#[cfg(feature = "system-collections-generic-dictionary_2")]
126pub use dictionary_2_ext::*;
127
128#[cfg(all(
129 feature = "app-gameuserdata",
130 feature = "app-gamevariable",
131 feature = "app-singletonclass_1",
132 feature = "system-collections-generic-list_1",
133))]
134mod game_variable_manager {
135 use unity::Il2CppString;
136
137 use crate::{
138 app::{
139 gameuserdata::{GameUserData, IGameUserDataMethods},
140 gamevariable::{GameVariable, IGameVariableMethods},
141 singletonclass_1::ISingletonClass_1Methods,
142 },
143 system::collections::generic::list_1::List_1,
144 };
145
146 pub struct GameVariableManager;
147
148 impl GameVariableManager {
149 #[inline]
150 fn variable() -> GameVariable {
151 GameUserData::get_instance().get_variable()
152 }
153
154 pub fn get_bool(key: impl Into<Il2CppString>) -> bool {
155 Self::variable().get_bool(key.into())
156 }
157
158 pub fn set_bool(key: impl Into<Il2CppString>, value: bool) {
159 Self::variable().set(key.into(), value);
160 }
161
162 pub fn get_number(key: impl Into<Il2CppString>) -> i32 {
163 Self::variable().get_number(key.into())
164 }
165
166 pub fn set_number(key: impl Into<Il2CppString>, value: i32) {
167 Self::variable().set_number(key.into(), value);
168 }
169
170 pub fn get_string(key: impl Into<Il2CppString>) -> Il2CppString {
171 Self::variable().get_string(key.into())
172 }
173
174 pub fn set_string(key: impl Into<Il2CppString>, value: impl Into<Il2CppString>) {
175 Self::variable().set_string(key.into(), value.into());
176 }
177
178 pub fn make_entry(key: impl Into<Il2CppString>, num: i32) -> bool {
179 Self::variable().entry(key.into(), num)
180 }
181
182 pub fn make_entry_norewind(key: impl Into<Il2CppString>, num: i32) -> bool {
183 Self::variable().entry_no_rewind(key.into(), num)
184 }
185
186 pub fn is_exist(key: impl Into<Il2CppString>) -> bool {
187 Self::variable().is_exist(key.into())
188 }
189
190 pub fn is_string(key: impl Into<Il2CppString>) -> bool {
191 Self::variable().is_string(key.into())
192 }
193
194 pub fn remove(key: impl Into<Il2CppString>) -> bool {
195 Self::variable().remove(key.into())
196 }
197
198 pub fn find_starts_with(prefix: impl Into<Il2CppString>) -> List_1<Il2CppString> {
199 Self::variable().find_starts_with(prefix.into())
200 }
201 }
202}
203#[cfg(all(
204 feature = "app-gameuserdata",
205 feature = "app-gamevariable",
206 feature = "app-singletonclass_1",
207 feature = "system-collections-generic-list_1",
208))]
209pub use game_variable_manager::*;
210
211#[cfg(feature = "app-mess")]
212mod mess_ext {
213 use unity::Il2CppString;
214
215 pub struct Mess;
216
217 impl Mess {
218 pub fn get(label: impl Into<Il2CppString>) -> Il2CppString {
219 crate::app::mess::Mess::get(label.into())
220 }
221
222 pub fn load(file_name: impl Into<Il2CppString>) -> bool {
223 crate::app::mess::Mess::load(file_name.into())
224 }
225
226 pub fn try_load(file_name: impl Into<Il2CppString>) -> bool {
227 crate::app::mess::Mess::try_load(file_name.into())
228 }
229
230 pub fn free(file_name: impl Into<Il2CppString>) -> bool {
231 crate::app::mess::Mess::free(file_name.into())
232 }
233
234 pub fn try_free(file_name: impl Into<Il2CppString>) -> bool {
235 crate::app::mess::Mess::try_free(file_name.into())
236 }
237
238 pub fn is_exist(label: impl Into<Il2CppString>) -> bool {
239 crate::app::mess::Mess::is_exist(label.into())
240 }
241
242 pub fn is_load_done(file_name: impl Into<Il2CppString>) -> bool {
243 crate::app::mess::Mess::is_load_done(file_name.into())
244 }
245
246 pub fn is_file_exist(file_name: impl Into<Il2CppString>) -> bool {
247 crate::app::mess::Mess::is_file_exist(file_name.into())
248 }
249
250 pub fn get_language_directory_name() -> Il2CppString {
251 crate::app::mess::Mess::get_language_directory_name()
252 }
253
254 pub fn get_file_path(label: impl Into<Il2CppString>) -> Il2CppString {
255 crate::app::mess::Mess::get_file_path(label.into())
256 }
257 }
258}
259#[cfg(feature = "app-mess")] pub use mess_ext::*;
260
261#[cfg(feature = "app-titlebar")]
262mod title_bar_ext {
263 use unity::Il2CppString;
264
265 pub struct TitleBar;
266
267 impl TitleBar {
268 pub fn open_header(title: impl Into<Il2CppString>, title_help: impl Into<Il2CppString>, key_help_id: impl Into<Il2CppString>) -> bool {
269 use crate::app::titlebar::{ITitleBarMethods, TitleBar as TB};
270 TB::get_instance().open_header(title.into(), title_help.into(), key_help_id.into())
271 }
272
273 pub fn close_header() {
274 use crate::app::titlebar::{ITitleBarMethods, TitleBar as TB};
275 TB::get_instance().close_header();
276 }
277 }
278}
279#[cfg(feature = "app-titlebar")]
280pub use title_bar_ext::*;
281
282#[cfg(all(feature = "app-pad", feature = "app-vibrationmanager"))]
283mod vibrate_ext {
284 pub const FREQ_LOW: f32 = 160.0;
285 pub const FREQ_HIGH: f32 = 300.0;
286
287 pub fn vibrate(time: f32, amplitude_magnitude: f32, amp_low: f32, amp_high: f32, freq_low: f32, freq_high: f32) {
288 use crate::app::{pad::Pad, vibrationmanager::IVibrationManagerMethods};
289 Pad::vibration().one_shot_2(time, amplitude_magnitude, amp_low, amp_high, freq_low, freq_high);
290 }
291}
292#[cfg(all(feature = "app-pad", feature = "app-vibrationmanager"))]
293pub use vibrate_ext::*;
294
295#[cfg(all(feature = "app-procvoidmethod", feature = "system-object"))]
296mod proc_void_method_ext {
297 use unity::{FromIlInstance, IlInstance, IntPtr, MethodInfo, OptionalMethod, SystemObject};
298
299 use crate::{app::procvoidmethod::ProcVoidMethod, system::object::Object};
300
301 pub trait ProcVoidMethodExt: Sized {
302 fn from_fn<T: crate::app::procinst::IProcInst>(target: T, callback: extern "C" fn(T, OptionalMethod)) -> Option<Self>;
306 fn from_raw_parts(target: IlInstance, method_info: &'static MethodInfo) -> Option<Self>;
307 }
308
309 impl ProcVoidMethodExt for ProcVoidMethod {
310 fn from_fn<T: crate::app::procinst::IProcInst>(target: T, callback: extern "C" fn(T, OptionalMethod)) -> Option<Self> {
311 let intptr = super::method_info_intptr(callback as *mut u8, 0);
312 Some(ProcVoidMethod::new(
313 <Object as FromIlInstance>::from_il_instance(target.as_instance()),
314 intptr,
315 ))
316 }
317
318 fn from_raw_parts(target: IlInstance, method_info: &'static MethodInfo) -> Option<Self> {
319 let intptr = IntPtr(method_info as *const MethodInfo as *mut ());
320 Some(ProcVoidMethod::new(<Object as FromIlInstance>::from_il_instance(target), intptr))
321 }
322 }
323}
324#[cfg(all(feature = "app-procvoidmethod", feature = "system-object"))]
325pub use proc_void_method_ext::*;
326
327#[cfg(all(feature = "app-procvoidfunction", feature = "app-procinst", feature = "system-object",))]
328mod proc_void_function_ext {
329 use unity::{FromIlInstance, IlInstance, OptionalMethod, SystemObject};
330
331 use crate::{app::procvoidfunction::ProcVoidFunction, system::object::Object};
332
333 pub trait ProcVoidFunctionExt: Sized {
334 fn from_fn<T: crate::app::procinst::IProcInst>(callback: extern "C" fn(T, OptionalMethod)) -> Option<Self>;
339
340 fn from_fn_with_target<T: crate::app::procinst::IProcInst, U: crate::app::procinst::IProcInst>(
344 target: T,
345 callback: extern "C" fn(T, U, OptionalMethod),
346 ) -> Option<Self>;
347 }
348
349 impl ProcVoidFunctionExt for ProcVoidFunction {
350 fn from_fn<T: crate::app::procinst::IProcInst>(callback: extern "C" fn(T, OptionalMethod)) -> Option<Self> {
351 let intptr = super::method_info_intptr(callback as *mut u8, 1);
354 Some(ProcVoidFunction::new(
355 <Object as FromIlInstance>::from_il_instance(IlInstance::null()),
356 intptr,
357 ))
358 }
359
360 fn from_fn_with_target<T: crate::app::procinst::IProcInst, U: crate::app::procinst::IProcInst>(
361 target: T,
362 callback: extern "C" fn(T, U, OptionalMethod),
363 ) -> Option<Self> {
364 let intptr = super::method_info_intptr(callback as *mut u8, 2);
367 Some(ProcVoidFunction::new(
368 <Object as FromIlInstance>::from_il_instance(target.as_instance()),
369 intptr,
370 ))
371 }
372 }
373}
374#[cfg(all(feature = "app-procvoidfunction", feature = "app-procinst", feature = "system-object",))]
375pub use proc_void_function_ext::*;
376
377#[cfg(all(feature = "app-procboolmethod", feature = "system-object"))]
378mod proc_bool_method_ext {
379 use unity::{FromIlInstance, OptionalMethod, SystemObject};
380
381 use crate::{app::procboolmethod::ProcBoolMethod, system::object::Object};
382
383 pub trait ProcBoolMethodExt: Sized {
384 fn from_fn<T: crate::app::procinst::IProcInst>(target: T, callback: extern "C" fn(T, OptionalMethod) -> bool) -> Option<Self>;
388 }
389
390 impl ProcBoolMethodExt for ProcBoolMethod {
391 fn from_fn<T: crate::app::procinst::IProcInst>(target: T, callback: extern "C" fn(T, OptionalMethod) -> bool) -> Option<Self> {
392 let intptr = super::method_info_intptr(callback as *mut u8, 0);
393 Some(ProcBoolMethod::new(
394 <Object as FromIlInstance>::from_il_instance(target.as_instance()),
395 intptr,
396 ))
397 }
398 }
399}
400#[cfg(all(feature = "app-procboolmethod", feature = "system-object"))]
401pub use proc_bool_method_ext::*;
402
403#[cfg(all(
404 feature = "app-proc",
405 feature = "app-procvoidmethod",
406 feature = "app-procvoidfunction",
407 feature = "app-procdesc",
408))]
409mod proc_ext {
410 use crate::app::{proc::Proc, procdesc::ProcDesc, procvoidfunction::ProcVoidFunction, procvoidmethod::ProcVoidMethod};
411
412 pub trait ProcExt {
413 fn call_method(method: ProcVoidMethod) -> ProcDesc;
414 fn call_function(function: ProcVoidFunction) -> ProcDesc;
415 }
416
417 impl ProcExt for Proc {
418 fn call_method(method: ProcVoidMethod) -> ProcDesc {
419 Proc::call_2(method)
420 }
421
422 fn call_function(function: ProcVoidFunction) -> ProcDesc {
423 Proc::call(function)
424 }
425 }
426}
427#[cfg(all(
428 feature = "app-proc",
429 feature = "app-procvoidmethod",
430 feature = "app-procvoidfunction",
431 feature = "app-procdesc",
432))]
433pub use proc_ext::*;
434
435#[cfg(feature = "app-procdesc")]
436mod proc_desc_patch {
437 use unity::Array;
438
439 use crate::app::procdesc::ProcDesc;
440 #[cfg(all(feature = "app-proc", feature = "app-procdesclabel"))]
441 use ::unity::Cast;
442 #[cfg(all(feature = "app-proc", feature = "app-procdesclabel"))]
443 use crate::app::proc::Proc;
444 #[cfg(all(feature = "app-proc", feature = "app-procdesclabel"))]
445 use crate::app::procdesclabel::{IProcDescLabel, ProcDescLabel};
446
447 pub struct ProcDescPatch {
448 original: Vec<ProcDesc>,
449 patches: Vec<(usize, Vec<ProcDesc>)>,
450 }
451
452 impl ProcDescPatch {
453 pub fn new(original: Array<ProcDesc>) -> Self {
454 Self {
455 original: original.iter().collect(),
456 patches: Vec::new(),
457 }
458 }
459
460 pub fn insert(mut self, position: usize, descs: impl IntoIterator<Item = ProcDesc>) -> Self {
461 self.patches.push((position, descs.into_iter().collect()));
462 self
463 }
464
465 pub fn finish(mut self) -> Array<ProcDesc> {
466 self.patches.sort_by_key(|patch| std::cmp::Reverse(patch.0));
467 for (pos, descs) in self.patches {
468 self.original.splice(pos..pos, descs);
469 }
470 Array::<ProcDesc>::from_slice(&self.original).expect("ProcDescPatch::finish: ProcDesc array allocation failed")
471 }
472 }
473
474 #[cfg(all(feature = "app-proc", feature = "app-procdesclabel"))]
475 impl ProcDescPatch {
476 fn next_free_label(&self) -> i32 {
477 self.original
478 .iter()
479 .filter_map(|desc| desc.try_cast::<ProcDescLabel>())
480 .map(|label| label.m_label())
481 .max()
482 .map(|highest| highest + 1)
483 .unwrap_or(31)
484 }
485
486 pub fn append_labeled_block(self, body: impl IntoIterator<Item = ProcDesc>) -> (Self, i32) {
487 let label = self.next_free_label();
488 let end = self.original.len();
489 let mut block = std::vec![Proc::label(label)];
490 block.extend(body);
491 (self.insert(end, block), label)
492 }
493 }
494}
495#[cfg(feature = "app-procdesc")]
496pub use proc_desc_patch::*;
497
498#[cfg(feature = "app-basicmenu")]
499mod basic_menu_result {
500 use crate::app::basicmenu::BasicMenu_Result;
501
502 #[repr(transparent)]
503 #[derive(Copy, Clone, PartialEq, Eq)]
504 pub struct BasicMenuResult(pub BasicMenu_Result);
505
506 impl Default for BasicMenuResult {
507 fn default() -> Self {
508 Self::new()
509 }
510 }
511
512 impl BasicMenuResult {
513 const CLOSE_ALL: i32 = 1 << 2;
514 const CLOSE_PARENT: i32 = 1 << 1;
515 const CLOSE_THIS: i32 = 1 << 0;
516 const DELETE_ALL: i32 = 1 << 5;
517 const DELETE_PARENT: i32 = 1 << 4;
518 const DELETE_THIS: i32 = 1 << 3;
519 const DO_NOTHING: i32 = 1 << 13;
520 const SE_CANCEL: i32 = 1 << 9;
521 const SE_CURSOR: i32 = 1 << 12;
522 const SE_DECIDE: i32 = 1 << 7;
523 const SE_DECIDE2: i32 = 1 << 8;
524 const SE_MISS: i32 = 1 << 11;
525
526 #[inline]
527 pub const fn new() -> Self {
528 Self(BasicMenu_Result { value: 0 })
529 }
530
531 #[inline]
532 pub const fn bits(self) -> i32 {
533 self.0.value
534 }
535
536 fn set(mut self, mask: i32, v: bool) -> Self {
537 if v {
538 self.0.value |= mask;
539 } else {
540 self.0.value &= !mask;
541 }
542 self
543 }
544
545 pub const fn close_this(self) -> bool {
546 self.0.value & Self::CLOSE_THIS != 0
547 }
548
549 pub const fn close_parent(self) -> bool {
550 self.0.value & Self::CLOSE_PARENT != 0
551 }
552
553 pub const fn close_all(self) -> bool {
554 self.0.value & Self::CLOSE_ALL != 0
555 }
556
557 pub const fn delete_this(self) -> bool {
558 self.0.value & Self::DELETE_THIS != 0
559 }
560
561 pub const fn delete_parent(self) -> bool {
562 self.0.value & Self::DELETE_PARENT != 0
563 }
564
565 pub const fn delete_all(self) -> bool {
566 self.0.value & Self::DELETE_ALL != 0
567 }
568
569 pub const fn do_nothing(self) -> bool {
570 self.0.value & Self::DO_NOTHING != 0
571 }
572
573 pub fn with_close_this(self, v: bool) -> Self {
574 self.set(Self::CLOSE_THIS, v)
575 }
576
577 pub fn with_close_parent(self, v: bool) -> Self {
578 self.set(Self::CLOSE_PARENT, v)
579 }
580
581 pub fn with_close_all(self, v: bool) -> Self {
582 self.set(Self::CLOSE_ALL, v)
583 }
584
585 pub fn with_delete_this(self, v: bool) -> Self {
586 self.set(Self::DELETE_THIS, v)
587 }
588
589 pub fn with_delete_parent(self, v: bool) -> Self {
590 self.set(Self::DELETE_PARENT, v)
591 }
592
593 pub fn with_delete_all(self, v: bool) -> Self {
594 self.set(Self::DELETE_ALL, v)
595 }
596
597 pub fn with_se_decide(self, v: bool) -> Self {
598 self.set(Self::SE_DECIDE, v)
599 }
600
601 pub fn with_se_decide2(self, v: bool) -> Self {
602 self.set(Self::SE_DECIDE2, v)
603 }
604
605 pub fn with_se_cancel(self, v: bool) -> Self {
606 self.set(Self::SE_CANCEL, v)
607 }
608
609 pub fn with_se_miss(self, v: bool) -> Self {
610 self.set(Self::SE_MISS, v)
611 }
612
613 pub fn with_se_cursor(self, v: bool) -> Self {
614 self.set(Self::SE_CURSOR, v)
615 }
616
617 pub fn with_do_nothing(self, v: bool) -> Self {
618 self.set(Self::DO_NOTHING, v)
619 }
620
621 pub fn se_cursor() -> Self {
622 Self::new().with_se_cursor(true)
623 }
624
625 pub fn se_decide() -> Self {
626 Self::new().with_se_decide(true)
627 }
628
629 pub fn close_decide() -> Self {
630 Self::new().with_close_this(true).with_se_decide(true)
631 }
632
633 pub fn se_miss() -> Self {
634 Self::new().with_se_miss(true)
635 }
636
637 pub fn close_parent_decide() -> Self {
638 Self::new().with_close_parent(true).with_se_decide(true)
639 }
640
641 pub fn delete_decide() -> Self {
642 Self::new().with_delete_this(true).with_se_decide(true)
643 }
644
645 pub fn close_cancel() -> Self {
646 Self::new().with_se_cancel(true).with_close_this(true)
647 }
648 }
649
650 impl ::unity::ClassIdentity for BasicMenuResult {
651 const NAME: &'static str = <BasicMenu_Result as ::unity::ClassIdentity>::NAME;
652 const NAMESPACE: &'static str = <BasicMenu_Result as ::unity::ClassIdentity>::NAMESPACE;
653
654 fn class() -> ::unity::Class {
655 <BasicMenu_Result as ::unity::ClassIdentity>::class()
656 }
657 }
658
659 impl ::unity::IlType for BasicMenuResult {
660 fn il_type() -> &'static ::unity::il2cpp::Il2CppType {
661 <BasicMenu_Result as ::unity::IlType>::il_type()
662 }
663 }
664}
665#[cfg(feature = "app-basicmenu")]
666pub use basic_menu_result::*;
667
668#[cfg(all(feature = "app-basicmenuitem", feature = "app-basicmenu"))]
669mod basic_menu_item_ext {
670 use unity::{Cast, Il2CppString, OptionalMethod};
671
672 use super::BasicMenuResult;
673 pub use crate::app::basicmenuitem::BasicMenuItem_Attribute as BasicMenuItemAttribute;
674 use crate::app::basicmenuitem::{BasicMenuItem, IBasicMenuItemMethods};
675
676 pub trait BasicMenuItemMethods {
677 extern "C" fn get_name(this: BasicMenuItem, method_info: OptionalMethod) -> Il2CppString;
678 extern "C" fn a_call(_this: BasicMenuItem, _method_info: OptionalMethod) -> BasicMenuResult {
679 BasicMenuResult::new()
680 }
681 extern "C" fn b_call(_this: BasicMenuItem, _method_info: OptionalMethod) -> BasicMenuResult {
682 BasicMenuResult::new().with_close_this(true).with_se_cancel(true)
683 }
684 extern "C" fn build_attribute(_this: BasicMenuItem, _method_info: OptionalMethod) -> BasicMenuItemAttribute {
685 BasicMenuItemAttribute::enable()
686 }
687 }
688
689 pub trait BasicMenuItemExt: Sized {
690 fn new_default() -> Self;
691 fn new_impl<M: BasicMenuItemMethods>() -> Self;
692 fn new_impl_from_template<M: BasicMenuItemMethods>(template: BasicMenuItem) -> Self;
693 }
694
695 impl BasicMenuItemExt for BasicMenuItem {
696 fn new_default() -> Self {
697 let item = <Self as ::unity::FromIlInstance>::instantiate().expect("BasicMenuItem::new_default allocation failed");
698 <Self as IBasicMenuItemMethods>::ctor(item);
699 item
700 }
701
702 fn new_impl<M: BasicMenuItemMethods>() -> Self {
703 let item = Self::new_default();
704 let class = item.override_class();
705 class.override_virtual_method("GetName", ::unity::method_info!(M::get_name, 0));
706 class.override_virtual_method("ACall", ::unity::method_info!(M::a_call, 0));
707 class.override_virtual_method("BCall", ::unity::method_info!(M::b_call, 0));
708 class.override_virtual_method("BuildAttribute", ::unity::method_info!(M::build_attribute, 0));
709 item
710 }
711
712 fn new_impl_from_template<M: BasicMenuItemMethods>(template: BasicMenuItem) -> Self {
713 use ::unity::FromIlInstance;
714 let cloned_class = template.get_class().clone_for_override();
715 let item =
716 <Self as FromIlInstance>::instantiate_with_class(cloned_class).expect("BasicMenuItem::new_impl_from_template allocation failed");
717 <Self as IBasicMenuItemMethods>::ctor(item);
718 cloned_class.override_virtual_method("GetName", ::unity::method_info!(M::get_name, 0));
719 cloned_class.override_virtual_method("ACall", ::unity::method_info!(M::a_call, 0));
720 cloned_class.override_virtual_method("BCall", ::unity::method_info!(M::b_call, 0));
721 cloned_class.override_virtual_method("BuildAttribute", ::unity::method_info!(M::build_attribute, 0));
722 item
723 }
724 }
725}
726#[cfg(all(feature = "app-basicmenuitem", feature = "app-basicmenu"))]
727pub use basic_menu_item_ext::*;
728
729#[cfg(all(
730 feature = "app-basicmenu",
731 feature = "app-basicmenucontent",
732 feature = "app-basicmenuitem",
733 feature = "app-procdesc",
734 feature = "system-collections-generic-list_1",
735))]
736mod basic_menu_ext {
737 use unity::Array;
738
739 use crate::{
740 app::{
741 basicmenu::{BasicMenu, IBasicMenu, IBasicMenuMethods},
742 basicmenucontent::BasicMenuContent,
743 basicmenuitem::BasicMenuItem,
744 procdesc::ProcDesc,
745 },
746 system::collections::generic::list_1::{IList_1Methods, List_1},
747 };
748
749 pub trait BasicMenuExt: Sized {
750 fn add_item(self, item: impl Into<BasicMenuItem>);
751 fn close_anime_all(self);
752 fn close_anime(self);
753 fn open_anime_all(self);
754 fn open_anime(self);
755 fn create_default_desc(self) -> Array<ProcDesc>;
756 fn build(menu_item_list: List_1<BasicMenuItem>, menu_content: BasicMenuContent) -> Self;
757 }
758
759 fn basic_menu_virtual_call_0(this: BasicMenu, method_name: &str) {
760 let class = ::unity::object_get_class(this);
761 let entry = class
762 .get_virtual_method(method_name)
763 .unwrap_or_else(|| panic!("BasicMenu vtable missing `{}`", method_name));
764 let f: extern "C" fn(BasicMenu, &'static ::unity::MethodInfo) = unsafe { ::core::mem::transmute(entry.method_ptr) };
765 f(this, entry.method_info)
766 }
767
768 impl BasicMenuExt for BasicMenu {
769 fn add_item(self, item: impl Into<BasicMenuItem>) {
770 self.m_full_menu_item_list().add(item.into());
771 }
772
773 fn close_anime_all(self) {
774 basic_menu_virtual_call_0(self, "CloseAnimeAll");
775 }
776
777 fn close_anime(self) {
778 basic_menu_virtual_call_0(self, "CloseAnime");
779 }
780
781 fn open_anime_all(self) {
782 basic_menu_virtual_call_0(self, "OpenAnimeAll");
783 }
784
785 fn open_anime(self) {
786 basic_menu_virtual_call_0(self, "OpenAnime");
787 }
788
789 fn create_default_desc(self) -> Array<ProcDesc> {
790 let class = ::unity::object_get_class(self);
791 let entry = class
792 .get_virtual_method("CreateDefaultDesc")
793 .expect("BasicMenu vtable missing `CreateDefaultDesc`");
794 let f: extern "C" fn(BasicMenu, &'static ::unity::MethodInfo) -> Array<ProcDesc> = unsafe { ::core::mem::transmute(entry.method_ptr) };
795 f(self, entry.method_info)
796 }
797
798 fn build(menu_item_list: List_1<BasicMenuItem>, menu_content: BasicMenuContent) -> Self {
799 let menu = <Self as ::unity::FromIlInstance>::instantiate().expect("BasicMenu::build allocation failed");
800 <Self as IBasicMenuMethods>::ctor(menu, menu_item_list, menu_content);
801 menu
802 }
803 }
804}
805#[cfg(all(
806 feature = "app-basicmenu",
807 feature = "app-basicmenucontent",
808 feature = "app-basicmenuitem",
809 feature = "app-procdesc",
810 feature = "system-collections-generic-list_1",
811))]
812pub use basic_menu_ext::*;
813
814#[cfg(all(feature = "app-soundmanager", feature = "app-soundsystem", feature = "system-collections-generic-list_1",))]
815mod sound_manager_ext {
816 use unity::{Cast, Il2CppString, MethodInfo};
817
818 use crate::{
819 app::{
820 soundmanager::{ISoundManager, SoundManager},
821 soundsystem::SoundSystem_SoundHandle,
822 },
823 system::collections::generic::list_1::IList_1Methods,
824 };
825
826 pub trait SoundManagerExt: Sized {
827 fn is_event_playing_with_prefix(self, prefix: impl AsRef<str>) -> bool;
828 }
829
830 fn sound_handle_event_name(handle: SoundSystem_SoundHandle) -> Il2CppString {
831 let class = ::unity::object_get_class(handle);
832 let entry = class
833 .get_virtual_method("GetEventName")
834 .expect("SoundSystem.SoundHandle vtable missing `GetEventName`");
835 let f: extern "C" fn(SoundSystem_SoundHandle, &'static MethodInfo) -> Il2CppString = unsafe { ::core::mem::transmute(entry.method_ptr) };
836 f(handle, entry.method_info)
837 }
838
839 impl SoundManagerExt for SoundManager {
840 fn is_event_playing_with_prefix(self, prefix: impl AsRef<str>) -> bool {
841 let prefix = prefix.as_ref();
842 let list = self.m_sound_handle_list();
843 let count = list.get_count();
844 (0..count).any(|i| {
845 let handle = list.get_item(i);
846 !handle.is_null() && sound_handle_event_name(handle).to_string().starts_with(prefix)
847 })
848 }
849 }
850}
851#[cfg(all(feature = "app-soundmanager", feature = "app-soundsystem", feature = "system-collections-generic-list_1",))]
852pub use sound_manager_ext::*;
853
854#[cfg(all(feature = "app-force", feature = "app-unit"))]
855mod force_ext {
856 use unity::Cast;
857
858 use crate::app::{
859 force::{Force, IForceMethods},
860 unit::{IUnitMethods, Unit},
861 };
862
863 pub trait ForceExt: Sized {
864 fn iter(self) -> ForceIter;
865 }
866
867 impl ForceExt for Force {
868 fn iter(self) -> ForceIter {
869 ForceIter { current: self.get_first() }
870 }
871 }
872
873 pub struct ForceIter {
874 current: Unit,
875 }
876
877 impl Iterator for ForceIter {
878 type Item = Unit;
879
880 fn next(&mut self) -> Option<Unit> {
881 if self.current.is_null() {
882 return None;
883 }
884 let unit = self.current;
885 self.current = unit.get_next();
886 Some(unit)
887 }
888 }
889}
890#[cfg(all(feature = "app-force", feature = "app-unit"))]
891pub use force_ext::*;
892
893#[cfg(all(feature = "root-configbasicmenuitem", feature = "app-basicmenuitem", feature = "app-basicmenu",))]
894mod config_basic_menu_item_ext {
895 use unity::{Cast, Il2CppString, OptionalMethod};
896
897 use super::{BasicMenuItemAttribute, BasicMenuResult};
898 use crate::root::configbasicmenuitem::{
899 ConfigBasicMenuItem, ConfigBasicMenuItem_ConfigMethodKind, IConfigBasicMenuItem, IConfigBasicMenuItemMethods,
900 };
901
902 pub trait ConfigBasicMenuItemSwitchMethods {
903 fn init_content(_this: ConfigBasicMenuItem) {}
904 extern "C" fn custom_call(this: ConfigBasicMenuItem, method_info: OptionalMethod) -> BasicMenuResult;
905 extern "C" fn set_command_text(this: ConfigBasicMenuItem, method_info: OptionalMethod);
906 extern "C" fn set_help_text(this: ConfigBasicMenuItem, method_info: OptionalMethod);
907 extern "C" fn a_call(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuResult {
908 BasicMenuResult::new()
909 }
910 extern "C" fn build_attribute(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuItemAttribute {
911 BasicMenuItemAttribute::enable()
912 }
913 }
914
915 pub trait ConfigBasicMenuItemCommandMethods {
916 fn init_content(_this: ConfigBasicMenuItem) {}
917 extern "C" fn custom_call(this: ConfigBasicMenuItem, method_info: OptionalMethod) -> BasicMenuResult;
918 extern "C" fn set_command_text(this: ConfigBasicMenuItem, method_info: OptionalMethod);
919 extern "C" fn set_help_text(this: ConfigBasicMenuItem, method_info: OptionalMethod);
920 extern "C" fn on_select(this: ConfigBasicMenuItem, _method_info: OptionalMethod) {
921 <ConfigBasicMenuItem as IConfigBasicMenuItemMethods>::on_select(this);
922 this.set_m_is_arrow(false);
923 <ConfigBasicMenuItem as IConfigBasicMenuItemMethods>::on_deselect(this);
924 }
925 extern "C" fn on_deselect(this: ConfigBasicMenuItem, _method_info: OptionalMethod) {
926 <ConfigBasicMenuItem as IConfigBasicMenuItemMethods>::on_select(this);
927 this.set_m_is_arrow(false);
928 <ConfigBasicMenuItem as IConfigBasicMenuItemMethods>::on_deselect(this);
929 }
930 extern "C" fn a_call(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuResult {
931 BasicMenuResult::new()
932 }
933 extern "C" fn build_attribute(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuItemAttribute {
934 BasicMenuItemAttribute::enable()
935 }
936 }
937
938 pub trait ConfigBasicMenuItemGaugeMethods {
939 fn init_content(_this: ConfigBasicMenuItem) {}
940 extern "C" fn custom_call(this: ConfigBasicMenuItem, method_info: OptionalMethod) -> BasicMenuResult;
941 extern "C" fn set_help_text(this: ConfigBasicMenuItem, method_info: OptionalMethod);
942 extern "C" fn a_call(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuResult {
943 BasicMenuResult::new()
944 }
945 extern "C" fn build_attribute(_this: ConfigBasicMenuItem, _method_info: OptionalMethod) -> BasicMenuItemAttribute {
946 BasicMenuItemAttribute::enable()
947 }
948 }
949
950 pub trait ConfigBasicMenuItemExt: Sized {
951 fn new_switch<M: ConfigBasicMenuItemSwitchMethods>(title: impl Into<Il2CppString>) -> Self;
952 fn new_command<M: ConfigBasicMenuItemCommandMethods>(title: impl Into<Il2CppString>) -> Self;
953 fn new_gauge<M: ConfigBasicMenuItemGaugeMethods>(title: impl Into<Il2CppString>) -> Self;
954 fn change_key_value_b(value: bool) -> bool;
955 }
956
957 impl ConfigBasicMenuItemExt for ConfigBasicMenuItem {
958 fn new_switch<M: ConfigBasicMenuItemSwitchMethods>(title: impl Into<Il2CppString>) -> Self {
959 let item = ConfigBasicMenuItem::new();
960 M::init_content(item);
961
962 item.set_m_config_method(ConfigBasicMenuItem_ConfigMethodKind::switch());
963 let class = item.override_class();
964 class.override_virtual_method("CustomCall", ::unity::method_info!(M::custom_call, 0));
965 class.override_virtual_method("ACall", ::unity::method_info!(M::a_call, 0));
966 class.override_virtual_method("BuildAttribute", ::unity::method_info!(M::build_attribute, 0));
967
968 item.set_title_text(title.into());
969 M::set_command_text(item, None);
970 M::set_help_text(item, None);
971
972 item
973 }
974
975 fn new_gauge<M: ConfigBasicMenuItemGaugeMethods>(title: impl Into<Il2CppString>) -> Self {
976 let item = ConfigBasicMenuItem::new();
977 M::init_content(item);
978
979 item.set_m_config_method(ConfigBasicMenuItem_ConfigMethodKind::gauge());
980 let class = item.override_class();
981 class.override_virtual_method("CustomCall", ::unity::method_info!(M::custom_call, 0));
982 class.override_virtual_method("ACall", ::unity::method_info!(M::a_call, 0));
983 class.override_virtual_method("BuildAttribute", ::unity::method_info!(M::build_attribute, 0));
984
985 item.set_title_text(title.into());
986 M::set_help_text(item, None);
987
988 item
989 }
990
991 fn new_command<M: ConfigBasicMenuItemCommandMethods>(title: impl Into<Il2CppString>) -> Self {
992 let item = ConfigBasicMenuItem::new();
993 M::init_content(item);
994
995 item.set_m_config_method(ConfigBasicMenuItem_ConfigMethodKind::switch());
996 item.set_m_is_arrow(false);
997 item.set_m_is_command_icon(true);
998 let class = item.override_class();
999 class.override_virtual_method("CustomCall", ::unity::method_info!(M::custom_call, 0));
1000 class.override_virtual_method("OnSelect", ::unity::method_info!(M::on_select, 0));
1001 class.override_virtual_method("OnDeselect", ::unity::method_info!(M::on_deselect, 0));
1002 class.override_virtual_method("ACall", ::unity::method_info!(M::a_call, 0));
1003 class.override_virtual_method("BuildAttribute", ::unity::method_info!(M::build_attribute, 0));
1004
1005 item.set_title_text(title.into());
1006 M::set_command_text(item, None);
1007 M::set_help_text(item, None);
1008
1009 item
1010 }
1011
1012 fn change_key_value_b(value: bool) -> bool {
1013 ConfigBasicMenuItem::change_key_value(value as i32, 0, 1, 1) == 1
1014 }
1015 }
1016}
1017#[cfg(all(feature = "root-configbasicmenuitem", feature = "app-basicmenuitem", feature = "app-basicmenu",))]
1018pub use config_basic_menu_item_ext::*;
1019
1020#[cfg(feature = "app-procinst")]
1021mod restore_parent_on_dispose_ext {
1022 use unity::{Cast, OptionalMethod};
1023
1024 pub extern "C" fn restore_parent_on_dispose(this: crate::app::procinst::ProcInst, _method_info: OptionalMethod) {
1025 use crate::app::procinst::IProcInstMethods;
1026 let parent = this.get_super();
1027 if parent.is_null() {
1028 return;
1029 }
1030 if let Some(slot) = parent.get_class().raw().get_virtual_method("OpenAnimeAll") {
1031 let f: extern "C" fn(crate::app::procinst::ProcInst, &'static ::unity::MethodInfo) = unsafe { ::core::mem::transmute(slot.method_ptr) };
1032 f(parent, slot.method_info);
1033 }
1034 }
1035}
1036#[cfg(feature = "app-procinst")]
1037pub use restore_parent_on_dispose_ext::*;
1038
1039#[cfg(all(
1040 feature = "app-basicdialog",
1041 feature = "app-yesmenuitem",
1042 feature = "app-basicdialogitem",
1043 feature = "app-basicdialogitemno",
1044 feature = "app-basicmenuitem",
1045 feature = "system-collections-generic-list_1",
1046 feature = "app-procinst",
1047 feature = "system-action",
1048))]
1049mod basic_menu_confirm_ext {
1050 use unity::Il2CppString;
1051
1052 use crate::{
1053 app::{
1054 basicdialog::{BasicDialog, IBasicDialogMethods},
1055 basicdialogitemno::{BasicDialogItemNo, IBasicDialogItemNoMethods},
1056 basicmenuitem::BasicMenuItem,
1057 yesmenuitem::{IYesMenuItemMethods, YesMenuItem},
1058 },
1059 system::{
1060 action::Action,
1061 collections::generic::list_1::{IList_1Methods, List_1},
1062 },
1063 };
1064
1065 pub fn basic_menu_confirm(
1066 proc: impl Into<crate::app::procinst::ProcInst>,
1067 message: impl Into<Il2CppString>,
1068 yes_text: impl Into<Il2CppString>,
1069 no_text: impl Into<Il2CppString>,
1070 handler: Action,
1071 ) -> BasicDialog {
1072 use crate::app::basicdialogitem::IBasicDialogItem;
1073 let yes_item = <YesMenuItem as ::unity::FromIlInstance>::instantiate().expect("YesMenuItem allocation failed");
1074 <YesMenuItem as IYesMenuItemMethods>::ctor(yes_item, handler);
1075 yes_item.set_m_text(yes_text.into());
1076
1077 let no_item = <BasicDialogItemNo as ::unity::FromIlInstance>::instantiate().expect("BasicDialogItemNo allocation failed");
1078 <BasicDialogItemNo as IBasicDialogItemNoMethods>::ctor_2(no_item, no_text.into());
1079
1080 let items = List_1::<BasicMenuItem>::new();
1081 items.add(yes_item.into());
1082 items.add(no_item.into());
1083
1084 let dialog = BasicDialog::create_basic_dialog_bind(proc.into(), items);
1085 dialog.set_text(message.into());
1086 dialog
1087 }
1088}
1089#[cfg(all(
1090 feature = "app-basicdialog",
1091 feature = "app-yesmenuitem",
1092 feature = "app-basicdialogitem",
1093 feature = "app-basicdialogitemno",
1094 feature = "app-basicmenuitem",
1095 feature = "system-collections-generic-list_1",
1096 feature = "app-procinst",
1097 feature = "system-action",
1098))]
1099pub use basic_menu_confirm_ext::*;
1100
1101#[cfg(all(
1102 feature = "app-yesnodialog",
1103 feature = "app-basicdialogitemyes",
1104 feature = "app-basicdialogitemno",
1105 feature = "app-procinst",
1106 feature = "app-basicmenu",
1107))]
1108mod yes_no_dialog_ext {
1109 use unity::{Cast, Il2CppString, OptionalMethod};
1110
1111 use super::BasicMenuResult;
1112 use crate::app::{
1113 basicdialogitemno::{BasicDialogItemNo, IBasicDialogItemNoMethods},
1114 basicdialogitemyes::{BasicDialogItemYes, IBasicDialogItemYesMethods},
1115 yesnodialog::YesNoDialog,
1116 };
1117
1118 pub trait TwoChoiceDialogMethods {
1119 extern "C" fn on_first_choice(_this: BasicDialogItemYes, _method_info: OptionalMethod) -> BasicMenuResult {
1120 BasicMenuResult::new().with_close_this(true)
1121 }
1122 extern "C" fn on_second_choice(_this: BasicDialogItemNo, _method_info: OptionalMethod) -> BasicMenuResult {
1123 BasicMenuResult::new().with_close_this(true)
1124 }
1125 extern "C" fn bcall_first(_this: BasicDialogItemYes, _method_info: OptionalMethod) -> BasicMenuResult {
1126 BasicMenuResult::new().with_close_this(true).with_se_cancel(true)
1127 }
1128 extern "C" fn bcall_second(_this: BasicDialogItemNo, _method_info: OptionalMethod) -> BasicMenuResult {
1129 BasicMenuResult::new().with_close_this(true).with_se_cancel(true)
1130 }
1131 }
1132
1133 pub trait YesNoDialogExt {
1134 fn bind_with<Methods: TwoChoiceDialogMethods>(
1135 proc: impl Into<crate::app::procinst::ProcInst>,
1136 message: impl Into<Il2CppString>,
1137 first_text: impl Into<Il2CppString>,
1138 second_text: impl Into<Il2CppString>,
1139 );
1140 }
1141
1142 impl YesNoDialogExt for YesNoDialog {
1143 fn bind_with<Methods: TwoChoiceDialogMethods>(
1144 proc: impl Into<crate::app::procinst::ProcInst>,
1145 message: impl Into<Il2CppString>,
1146 first_text: impl Into<Il2CppString>,
1147 second_text: impl Into<Il2CppString>,
1148 ) {
1149 let yes = <BasicDialogItemYes as ::unity::FromIlInstance>::instantiate().expect("BasicDialogItemYes allocation failed");
1150 <BasicDialogItemYes as IBasicDialogItemYesMethods>::ctor_2(yes, first_text.into());
1151 let no = <BasicDialogItemNo as ::unity::FromIlInstance>::instantiate().expect("BasicDialogItemNo allocation failed");
1152 <BasicDialogItemNo as IBasicDialogItemNoMethods>::ctor_2(no, second_text.into());
1153
1154 let yes_class = yes.override_class();
1155 let no_class = no.override_class();
1156
1157 let on_first = ::unity::method_info!(Methods::on_first_choice, 0);
1158 let bcall_first = ::unity::method_info!(Methods::bcall_first, 0);
1159 let on_second = ::unity::method_info!(Methods::on_second_choice, 0);
1160 let bcall_second = ::unity::method_info!(Methods::bcall_second, 0);
1161
1162 yes_class.override_virtual_method("ACall", on_first);
1163 yes_class.override_virtual_method("BCall", bcall_first);
1164 no_class.override_virtual_method("ACall", on_second);
1165 no_class.override_virtual_method("BCall", bcall_second);
1166
1167 let _ = YesNoDialog::create_bind(proc.into(), message.into(), yes, no);
1168 }
1169 }
1170}
1171#[cfg(all(
1172 feature = "app-yesnodialog",
1173 feature = "app-basicdialogitemyes",
1174 feature = "app-basicdialogitemno",
1175 feature = "app-procinst",
1176 feature = "app-basicmenu",
1177))]
1178pub use yes_no_dialog_ext::*;
1179
1180#[cfg(feature = "app-filedata")]
1181mod file_handle_ext {
1182 use unity::MethodInfo;
1183
1184 #[::unity::class(namespace = "App", name = "FileHandle`1")]
1185 pub struct FileHandle {
1186 #[rename(name = "m_Data")]
1187 pub m_data: crate::app::filedata::FileData,
1188 }
1189
1190 impl FileHandle {
1191 pub fn unload(self) {
1192 let class = ::unity::object_get_class(self);
1193 let method = class
1194 .get_method_from_name("Unload", 0)
1195 .expect("FileHandle::Unload missing from runtime class");
1196 let unload: extern "C" fn(Self, &MethodInfo) = unsafe { ::core::mem::transmute(method.method_ptr) };
1197 unload(self, method);
1198 }
1199 }
1200}
1201#[cfg(feature = "app-filedata")]
1202pub use file_handle_ext::*;
1203
1204#[cfg(all(
1205 feature = "app-itemdata",
1206 feature = "app-scriptutil",
1207 feature = "moon_sharp-interpreter-dynvalue",
1208 feature = "app-unit",
1209))]
1210mod dyn_value_args_ext {
1211 use unity::{Array, FromIlInstance, Il2CppString, IlInstance};
1212
1213 use crate::{
1214 app::{itemdata::ItemData, scriptutil::ScriptUtil, unit::Unit},
1215 moon_sharp::interpreter::dynvalue::DynValue,
1216 };
1217
1218 pub trait DynValueArgs {
1219 fn try_get_i32(self, index: i32) -> i32;
1220 fn try_get_string(self, index: i32) -> Il2CppString;
1221 fn try_get_unit(self, index: i32) -> Unit;
1222 fn try_get_item(self, index: i32) -> ItemData;
1223 }
1224
1225 impl DynValueArgs for Array<DynValue> {
1226 fn try_get_i32(self, index: i32) -> i32 {
1227 ScriptUtil::try_get_int(self, index, i32::MAX)
1228 }
1229
1230 fn try_get_string(self, index: i32) -> Il2CppString {
1231 ScriptUtil::try_get_string(self, index, Il2CppString::from_il_instance(IlInstance::null()))
1232 }
1233
1234 fn try_get_unit(self, index: i32) -> Unit {
1235 ScriptUtil::try_get_unit(self, index, true)
1236 }
1237
1238 fn try_get_item(self, index: i32) -> ItemData {
1239 ScriptUtil::try_get_item(self, index, true)
1240 }
1241 }
1242}
1243#[cfg(all(
1244 feature = "app-itemdata",
1245 feature = "app-scriptutil",
1246 feature = "moon_sharp-interpreter-dynvalue",
1247 feature = "app-unit",
1248))]
1249pub use dyn_value_args_ext::*;
1250
1251#[cfg(all(feature = "app-eventscript", feature = "moon_sharp-interpreter-dynvalue"))]
1252mod event_script_ext {
1253 use unity::{Array, Class, FromIlInstance, Il2CppString, IlInstance, IntPtr, MethodInfo, OptionalMethod};
1254
1255 use crate::{
1256 app::eventscript::{EventScript, EventScript_ActionArgs, EventScript_FunctionArgs, IEventScriptMethods},
1257 moon_sharp::interpreter::dynvalue::DynValue,
1258 };
1259
1260 #[::unity::class(namespace = "App", name = "EventScript.ActionArgs")]
1261 pub struct EventScriptActionArgsExt {
1262 #[rename(name = "method_ptr")]
1263 pub method_ptr: ::unity::IntPtr,
1264 #[rename(name = "m_target")]
1265 pub m_target: ::unity::IlInstance,
1266 #[rename(name = "method")]
1267 pub method: ::unity::IntPtr,
1268 }
1269
1270 #[::unity::class(namespace = "App", name = "EventScript.FunctionArgs")]
1271 pub struct EventScriptFunctionArgsExt {
1272 #[rename(name = "method_ptr")]
1273 pub method_ptr: ::unity::IntPtr,
1274 #[rename(name = "m_target")]
1275 pub m_target: ::unity::IlInstance,
1276 #[rename(name = "method")]
1277 pub method: ::unity::IntPtr,
1278 }
1279
1280 fn clone_invoke_method_info(method_ptr: *mut u8) -> &'static MethodInfo {
1281 use std::{collections::HashMap, sync::Mutex};
1282
1283 static CACHE: Mutex<Option<HashMap<usize, &'static MethodInfo>>> = Mutex::new(None);
1284
1285 let mut guard = CACHE.lock().unwrap();
1286 let map = guard.get_or_insert_with(HashMap::new);
1287 let key = method_ptr as usize;
1288 if let Some(mi) = map.get(&key) {
1289 return mi;
1290 }
1291 let donor = Class::lookup("App", "ScriptSystem")
1292 .raw()
1293 .get_method_from_name("Log", 1)
1294 .expect("App.ScriptSystem::Log(args) donor missing");
1295 let mut cloned: MethodInfo = *donor;
1296 cloned.method_ptr = method_ptr;
1297 let leaked: &'static MethodInfo = Box::leak(Box::new(cloned));
1298 map.insert(key, leaked);
1299 leaked
1300 }
1301
1302 fn make_action_args(callback: *mut u8) -> EventScript_ActionArgs {
1303 let mi = clone_invoke_method_info(callback);
1304 let instance = <EventScriptActionArgsExt as FromIlInstance>::instantiate().expect("EventScript.ActionArgs allocation failed");
1305 instance.set_method_ptr(IntPtr(callback as *mut ()));
1306 instance.set_m_target(IlInstance::null());
1307 instance.set_method(IntPtr(mi as *const MethodInfo as *mut ()));
1308 EventScript_ActionArgs::from_il_instance(IlInstance::from(instance))
1309 }
1310
1311 fn make_function_args(callback: *mut u8) -> EventScript_FunctionArgs {
1312 let mi = clone_invoke_method_info(callback);
1313 let instance = <EventScriptFunctionArgsExt as FromIlInstance>::instantiate().expect("EventScript.FunctionArgs allocation failed");
1314 instance.set_method_ptr(IntPtr(callback as *mut ()));
1315 instance.set_m_target(IlInstance::null());
1316 instance.set_method(IntPtr(mi as *const MethodInfo as *mut ()));
1317 EventScript_FunctionArgs::from_il_instance(IlInstance::from(instance))
1318 }
1319
1320 pub trait EventScriptExt {
1321 fn register_action(self, name: impl Into<Il2CppString>, callback: extern "C" fn(Array<DynValue>, OptionalMethod));
1322 fn register_function(self, name: impl Into<Il2CppString>, callback: extern "C" fn(Array<DynValue>, OptionalMethod) -> DynValue);
1323 }
1324
1325 impl EventScriptExt for EventScript {
1326 fn register_action(self, name: impl Into<Il2CppString>, callback: extern "C" fn(Array<DynValue>, OptionalMethod)) {
1327 let args = make_action_args(callback as *mut u8);
1328 self.regist_action(args, name.into());
1329 }
1330
1331 fn register_function(self, name: impl Into<Il2CppString>, callback: extern "C" fn(Array<DynValue>, OptionalMethod) -> DynValue) {
1332 let args = make_function_args(callback as *mut u8);
1333 self.regist_function(args, name.into());
1334 }
1335 }
1336}
1337#[cfg(all(feature = "app-eventscript", feature = "moon_sharp-interpreter-dynvalue"))]
1338pub use event_script_ext::*;
1339
1340#[cfg(all(feature = "unity_engine-assetbundle", feature = "unity_engine-assetbundlecreaterequest",))]
1341mod asset_bundle_ext {
1342 use unity::{Array, OptionalMethod};
1343
1344 use crate::unity_engine::{assetbundle::AssetBundle, assetbundlecreaterequest::AssetBundleCreateRequest};
1345
1346 #[skyline::from_offset(0x491ff0)]
1347 unsafe fn engage_method_from_full_name(name: *const u8) -> *const u8;
1348
1349 fn lookup_method_by_signature(full_signature: &str) -> *const u8 {
1350 let c = std::ffi::CString::new(full_signature).unwrap();
1351 unsafe { engage_method_from_full_name(c.as_ptr() as *const u8) }
1352 }
1353
1354 pub trait AssetBundleExt {
1355 fn load_from_memory_async_internal(binary: Array<u8>, crc: u32) -> AssetBundleCreateRequest;
1356 }
1357
1358 impl AssetBundleExt for AssetBundle {
1359 fn load_from_memory_async_internal(binary: Array<u8>, crc: u32) -> AssetBundleCreateRequest {
1360 static METHOD_PTR: ::std::sync::OnceLock<usize> = ::std::sync::OnceLock::new();
1361 let ptr = *METHOD_PTR.get_or_init(|| {
1362 let p = lookup_method_by_signature("UnityEngine.AssetBundle::LoadFromMemoryAsync_Internal(System.Byte[],System.UInt32)");
1363 assert!(
1364 !p.is_null(),
1365 "UnityEngine.AssetBundle.LoadFromMemoryAsync_Internal not found via runtime full-signature lookup"
1366 );
1367 p as usize
1368 });
1369
1370 type RawFn = extern "C" fn(Array<u8>, u32, OptionalMethod) -> AssetBundleCreateRequest;
1371 let f: RawFn = unsafe { ::std::mem::transmute(ptr) };
1372 f(binary, crc, None)
1373 }
1374 }
1375}
1376#[cfg(all(feature = "unity_engine-assetbundle", feature = "unity_engine-assetbundlecreaterequest",))]
1377pub use asset_bundle_ext::*;