@@ -11,25 +11,27 @@ import {
11
11
import Ionicons from 'react-native-vector-icons/Ionicons'
12
12
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
13
13
14
- import globalStyle from '../globalStyle'
15
- import useDarkMode from '../context/useDarkMode'
16
- import SettingsContext from '../context/settingsContext'
17
- import ConnectionContext from '../context/connectionContext'
14
+ import packetHandler from './packetHandler'
15
+ import globalStyle from '../../globalStyle'
16
+ import useDarkMode from '../../context/useDarkMode'
17
+ import SettingsContext from '../../context/settingsContext'
18
+ import ConnectionContext from '../../context/connectionContext'
18
19
import {
19
20
ChatToJsx ,
20
- parseValidJson ,
21
21
mojangColorMap ,
22
22
lightColorMap ,
23
23
MinecraftChat ,
24
24
ClickEvent ,
25
25
ColorMap
26
- } from '../minecraft/chatToJsx'
27
- import { protocolMap , readVarInt , writeVarInt } from '../minecraft/utils'
28
- import { concatPacketData } from '../minecraft/packet'
29
- import TextField from '../components/TextField'
30
- import Text from '../components/Text'
26
+ } from '../../minecraft/chatToJsx'
27
+ import { protocolMap , writeVarInt } from '../../minecraft/utils'
28
+ import { concatPacketData } from '../../minecraft/packet'
29
+ import TextField from '../../components/TextField'
30
+ import Text from '../../components/Text'
31
+ import SettingScreen from '../settings/SettingScreen'
31
32
32
- import SettingScreen from './settings/SettingScreen'
33
+ const enderChatPrefix = '\u00A74[\u00A7cEnderChat\u00A74] \u00A7c'
34
+ const sendMessageErr = 'Failed to send message to server!'
33
35
34
36
type ChatNavigationProp = NativeStackNavigationProp <
35
37
{ Home : undefined ; Chat : undefined } ,
@@ -40,22 +42,20 @@ interface Message {
40
42
text : MinecraftChat
41
43
}
42
44
43
- const renderItem = (
44
- colorMap : ColorMap ,
45
- clickEventHandler : ( ce : ClickEvent ) => void
46
- ) => {
45
+ const renderItem = ( colorMap : ColorMap , handleCe : ( ce : ClickEvent ) => void ) => {
47
46
const ItemRenderer = ( { item } : { item : Message } ) => (
48
47
< View style = { styles . androidScaleInvert } >
49
48
< ChatToJsx
50
49
chat = { item . text }
51
50
component = { Text }
52
51
colorMap = { colorMap }
53
- clickEventHandler = { clickEventHandler }
52
+ clickEventHandler = { handleCe }
54
53
/>
55
54
</ View >
56
55
)
57
- return ItemRenderer // LOW-TODO: Performance implications?
58
- } // https://reactnative.dev/docs/optimizing-flatlist-configuration
56
+ // LOW-TODO: Performance implications? https://reactnative.dev/docs/optimizing-flatlist-configuration
57
+ return ItemRenderer
58
+ }
59
59
const ChatMessageList = ( props : {
60
60
messages : Message [ ]
61
61
colorMap : ColorMap
@@ -73,15 +73,7 @@ const ChatMessageList = (props: {
73
73
}
74
74
const ChatMessageListMemo = React . memo ( ChatMessageList ) // Shallow prop compare.
75
75
76
- const enderChatPrefix = '\u00A74[\u00A7cEnderChat\u00A74] \u00A7c'
77
- const sendMessageErr = 'Failed to send message to server!'
78
- const parseMessageErr = 'An error occurred when parsing chat.'
79
- const inventoryCloseErr = 'An error occurred when closing an inventory window.'
80
- const respawnErr = 'An error occurred when trying to respawn after death.'
81
- const deathRespawnMessage = enderChatPrefix + 'You died! Respawning...'
82
- const healthMessage =
83
- enderChatPrefix + "You're losing health! \u00A7b%prev \u00A7f-> \u00A7c%new"
84
- const errorHandler =
76
+ const handleError =
85
77
( addMessage : ( text : MinecraftChat ) => void , translated : string ) =>
86
78
( error : unknown ) => {
87
79
console . error ( error )
@@ -99,11 +91,8 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
99
91
const [ messages , setMessages ] = useState < Message [ ] > ( [ ] )
100
92
const [ loggedIn , setLoggedIn ] = useState ( false )
101
93
const [ message , setMessage ] = useState ( '' )
102
- const loggedInRef = useRef ( false )
103
94
const idRef = useRef ( 0 )
104
95
105
- const healthRef = useRef < number | null > ( null )
106
-
107
96
const charLimit =
108
97
connection && connection . connection . options . protocolVersion >= 306 // 16w38a
109
98
? 256
@@ -115,98 +104,25 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
115
104
} )
116
105
117
106
// Packet handler useEffect.
107
+ const loggedInRef = useRef ( false )
108
+ const healthRef = useRef < number | null > ( null )
118
109
useEffect ( ( ) => {
119
110
if ( ! connection ) return
120
- connection . connection . on ( 'packet' , packet => {
121
- if ( ! loggedInRef . current && connection . connection . loggedIn ) {
122
- setLoggedIn ( true )
123
- loggedInRef . current = true
124
- if ( settings . sendJoinMessage ) {
125
- connection . connection
126
- . writePacket (
127
- 0x03 ,
128
- concatPacketData ( [ settings . joinMessage . substring ( 0 , charLimit ) ] )
129
- )
130
- . catch ( errorHandler ( addMessage , sendMessageErr ) )
131
- }
132
- if ( settings . sendSpawnCommand ) {
133
- connection . connection
134
- . writePacket ( 0x03 , concatPacketData ( [ '/spawn' ] ) )
135
- . catch ( errorHandler ( addMessage , sendMessageErr ) )
136
- }
137
- } else if (
138
- packet . id === 0x0f /* Chat Message (clientbound) */ &&
139
- connection . connection . options . protocolVersion < protocolMap [ '1.19' ]
140
- ) {
141
- try {
142
- const [ chatLength , chatVarIntLength ] = readVarInt ( packet . data )
143
- const chatJson = packet . data
144
- . slice ( chatVarIntLength , chatVarIntLength + chatLength )
145
- . toString ( 'utf8' )
146
- const position = packet . data . readInt8 ( chatVarIntLength + chatLength )
147
- // TODO: Support position 2 (also in 0x5f packet) and sender for disableChat/blocked players.
148
- if ( position === 0 || position === 1 ) {
149
- addMessage ( parseValidJson ( chatJson ) )
150
- }
151
- } catch ( e ) {
152
- errorHandler ( addMessage , parseMessageErr ) ( e )
153
- }
154
- } else if (
155
- packet . id === 0x30 /* Player Chat Message (clientbound) */ &&
156
- connection . connection . options . protocolVersion >= protocolMap [ '1.19' ]
157
- ) {
158
- // TODO-1.19: Support player chat messages.
159
- } else if (
160
- packet . id === 0x5f /* System Chat Message (clientbound) */ &&
161
- connection . connection . options . protocolVersion >= protocolMap [ '1.19' ]
162
- ) {
163
- try {
164
- const [ chatLength , chatVarIntLength ] = readVarInt ( packet . data )
165
- const chatJson = packet . data
166
- . slice ( chatVarIntLength , chatVarIntLength + chatLength )
167
- . toString ( 'utf8' )
168
- const position = packet . data . readInt8 ( chatVarIntLength + chatLength )
169
- // TODO-1.19 - 3: say command, 4: msg command, 5: team msg command, 6: emote command, 7: tellraw command
170
- if ( position === 0 || position === 1 ) {
171
- addMessage ( parseValidJson ( chatJson ) )
172
- }
173
- } catch ( e ) {
174
- errorHandler ( addMessage , parseMessageErr ) ( e )
175
- }
176
- } else if ( packet . id === 0x2e /* Open Window */ ) {
177
- // Just close the window.
178
- const [ windowId ] = readVarInt ( packet . data )
179
- const buf = Buffer . alloc ( 1 )
180
- buf . writeUInt8 ( windowId )
181
- connection . connection // Close Window (serverbound)
182
- . writePacket ( 0x09 , buf )
183
- . catch ( errorHandler ( addMessage , inventoryCloseErr ) )
184
- } else if ( packet . id === 0x35 /* Death Combat Event */ ) {
185
- const [ , playerIdLen ] = readVarInt ( packet . data )
186
- const offset = playerIdLen + 4 // Entity ID
187
- const [ chatLen , chatVarIntLength ] = readVarInt ( packet . data , offset )
188
- const jsonOffset = offset + chatVarIntLength
189
- const deathMessage = parseValidJson (
190
- packet . data . slice ( jsonOffset , jsonOffset + chatLen ) . toString ( 'utf8' )
191
- )
192
- addMessage ( deathRespawnMessage )
193
- if ( deathMessage ?. text || deathMessage ?. extra ) addMessage ( deathMessage )
194
- // Automatically respawn.
195
- // LOW-TODO: Should this be manual, or a dialog, like MC?
196
- connection . connection // Client Status
197
- . writePacket ( 0x04 , writeVarInt ( 0 ) )
198
- . catch ( errorHandler ( addMessage , respawnErr ) )
199
- } else if ( packet . id === 0x52 /* Update Health */ ) {
200
- const newHealth = packet . data . readFloatBE ( 0 )
201
- if ( healthRef . current != null && healthRef . current > newHealth ) {
202
- const info = healthMessage
203
- . replace ( '%prev' , healthRef . current . toString ( ) )
204
- . replace ( '%new' , newHealth . toString ( ) )
205
- addMessage ( info )
206
- } // LOW-TODO: Long-term it would be better to have a UI.
207
- healthRef . current = newHealth
208
- }
209
- } )
111
+ connection . connection . on (
112
+ 'packet' ,
113
+ packetHandler (
114
+ healthRef ,
115
+ loggedInRef ,
116
+ setLoggedIn ,
117
+ connection . connection ,
118
+ addMessage ,
119
+ settings . joinMessage ,
120
+ settings . sendJoinMessage ,
121
+ settings . sendSpawnCommand ,
122
+ handleError ,
123
+ charLimit
124
+ )
125
+ )
210
126
return ( ) => {
211
127
connection . connection . removeAllListeners ( 'packet' )
212
128
}
@@ -240,15 +156,15 @@ const ChatScreen = ({ navigation }: { navigation: ChatNavigationProp }) => {
240
156
if ( connection . connection . options . protocolVersion < protocolMap [ '1.19' ] ) {
241
157
connection . connection
242
158
. writePacket ( 0x03 , concatPacketData ( [ msg ] ) )
243
- . catch ( errorHandler ( addMessage , sendMessageErr ) )
159
+ . catch ( handleError ( addMessage , sendMessageErr ) )
244
160
} else {
245
161
const timestamp = Buffer . alloc ( 8 )
246
162
connection . connection
247
163
. writePacket (
248
164
0x04 ,
249
165
concatPacketData ( [ msg , timestamp , writeVarInt ( 0 ) , false ] )
250
166
)
251
- . catch ( errorHandler ( addMessage , sendMessageErr ) )
167
+ . catch ( handleError ( addMessage , sendMessageErr ) )
252
168
// TODO-1.19: Support sending Chat Command/Chat Message/Chat Preview.
253
169
}
254
170
}
@@ -351,9 +267,7 @@ const styles = StyleSheet.create({
351
267
backButton : { marginRight : 8 } ,
352
268
backButtonIcon : { marginRight : 0 } ,
353
269
sendButtonIcon : { marginRight : 0 , marginLeft : 4 } ,
354
- androidScaleInvert : {
355
- scaleY : Platform . OS === 'android' ? - 1 : undefined
356
- } ,
270
+ androidScaleInvert : { scaleY : Platform . OS === 'android' ? - 1 : undefined } ,
357
271
chatArea : { padding : 8 , flex : 1 , scaleY : - 1 } ,
358
272
chatAreaScrollView : { paddingBottom : 16 } ,
359
273
loadingScreen : { flex : 1 , alignItems : 'center' , justifyContent : 'center' } ,
0 commit comments