1use std::io::{self, Read, Write};
7
8use crate::net::bundle::{BundleElementWriter, TopElementReader, BundleElement, BundleResult};
9use crate::util::io::*;
10
11use super::{SimpleElement, TopElement, NoopElement, ElementLength, ElementIdRange};
12use super::entity::{MethodCall, MethodCallWrapper, MethodCallExt};
13
14
15pub mod id {
18
19 use super::ElementIdRange;
20
21 pub const CLIENT_AUTH: u8 = 0x00;
22 pub const CLIENT_SESSION_KEY: u8 = 0x01;
23
24 pub const CELL_ENTITY_METHOD: ElementIdRange = ElementIdRange::new(0x0F, 0x87);
25 pub const BASE_ENTITY_METHOD: ElementIdRange = ElementIdRange::new(0x88, 0xFE);
26
27}
28
29
30#[derive(Debug, Clone)]
37pub struct ClientAuth {
38 pub login_key: u32,
41 pub attempts_count: u8,
43 pub unk: u16,
45}
46
47impl SimpleElement for ClientAuth {
48
49 fn encode(&self, write: &mut impl Write) -> io::Result<()> {
50 write.write_u32(self.login_key)?;
51 write.write_u8(self.attempts_count)?;
52 write.write_u16(self.unk)
53 }
54
55 fn decode(read: &mut impl Read, _len: usize) -> io::Result<Self> {
56 Ok(Self {
57 login_key: read.read_u32()?,
58 attempts_count: read.read_u8()?,
59 unk: read.read_u16()?,
60 })
61 }
62
63}
64
65impl TopElement for ClientAuth {
66 const LEN: ElementLength = ElementLength::Fixed(7);
67}
68
69
70#[derive(Debug, Clone)]
73pub struct ServerSessionKey {
74 pub session_key: u32,
76}
77
78impl SimpleElement for ServerSessionKey {
79
80 fn encode(&self, write: &mut impl Write) -> io::Result<()> {
81 write.write_u32(self.session_key)
82 }
83
84 fn decode(read: &mut impl Read, _len: usize) -> io::Result<Self> {
85 Ok(Self { session_key: read.read_u32()? })
86 }
87
88}
89
90
91#[derive(Debug, Clone)]
95pub struct ClientSessionKey {
96 pub session_key: u32,
98}
99
100impl ClientSessionKey {
101 pub const ID: u8 = 0x01;
102}
103
104impl SimpleElement for ClientSessionKey {
105
106 fn encode(&self, write: &mut impl Write) -> io::Result<()> {
107 write.write_u32(self.session_key)
108 }
109
110 fn decode(read: &mut impl Read, _len: usize) -> io::Result<Self> {
111 Ok(Self { session_key: read.read_u32()? })
112 }
113
114}
115
116impl TopElement for ClientSessionKey {
117 const LEN: ElementLength = ElementLength::Fixed(4);
118}
119
120
121#[derive(Debug, Clone)]
124pub struct CellEntityMethod<M: MethodCall> {
125 pub entity_id: u32,
128 pub method: M,
130}
131
132impl<M: MethodCall> CellEntityMethod<M> {
133
134 pub fn write(self, writer: BundleElementWriter) {
136 MethodCallWrapper::new(self.method, CellEntityMethodExt {
137 entity_id: self.entity_id,
138 }).write(writer);
139 }
140
141 pub fn read(reader: TopElementReader) -> BundleResult<BundleElement<Self>> {
143 MethodCallWrapper::<M, CellEntityMethodExt>::read(reader).map(|res| {
144 res.map(|wrapper| Self {
145 entity_id: wrapper.ext.entity_id,
146 method: wrapper.method,
147 })
148 })
149 }
150
151}
152
153struct CellEntityMethodExt {
154 entity_id: u32,
155}
156
157impl MethodCallExt for CellEntityMethodExt {
158 const ID_RANGE: ElementIdRange = id::CELL_ENTITY_METHOD;
159}
160
161impl SimpleElement for CellEntityMethodExt {
162
163 fn encode(&self, write: &mut impl Write) -> io::Result<()> {
164 write.write_u32(self.entity_id)
165 }
166
167 fn decode(read: &mut impl Read, _len: usize) -> io::Result<Self> {
168 Ok(Self { entity_id: read.read_u32()? })
169 }
170
171}
172
173impl TopElement for CellEntityMethodExt {
174 const LEN: ElementLength = ElementLength::Variable16;
175}
176
177
178#[derive(Debug, Clone)]
181pub struct BaseEntityMethod<M: MethodCall> {
182 pub method: M,
183}
184
185impl<M: MethodCall> BaseEntityMethod<M> {
186
187 pub fn write(self, writer: BundleElementWriter) {
189 MethodCallWrapper::new(self.method, BaseEntityMethodExt).write(writer);
190 }
191
192 pub fn read(reader: TopElementReader) -> BundleResult<BundleElement<Self>> {
194 MethodCallWrapper::<M, BaseEntityMethodExt>::read(reader).map(|res| {
195 res.map(|wrapper| Self {
196 method: wrapper.method,
197 })
198 })
199 }
200
201}
202
203#[derive(Default)]
204struct BaseEntityMethodExt;
205
206impl MethodCallExt for BaseEntityMethodExt {
207 const ID_RANGE: ElementIdRange = id::BASE_ENTITY_METHOD;
208}
209
210impl NoopElement for BaseEntityMethodExt {}
211
212impl TopElement for BaseEntityMethodExt {
213 const LEN: ElementLength = ElementLength::Variable16;
214}