@@ -6,6 +6,13 @@ function parseNumber (str) {
66 return number
77}
88
9+ function anyToString ( obj ) {
10+ if ( typeof obj === 'boolean' ) {
11+ return obj ? 'True' : 'False'
12+ }
13+ return String ( obj )
14+ }
15+
916/**
1017 * Implements the LAN protocol for UnrealEngine3 based games (UE3)
1118 */
@@ -72,7 +79,21 @@ export default class unrealengine3lan extends CoreLAN {
7279 if ( outputAsArray && Array . isArray ( state ) ) {
7380 state . push ( ...resultStates )
7481 } else {
75- const firstPacket = resultStates . length ? { ...resultStates [ 0 ] , $next : resultStates . slice ( 1 ) . reduceRight ( ( next , value ) => ( { ...value , $next : next } ) , null ) } : null
82+ // add linker as state root
83+ // const firstPacket = resultStates.length ? { ...resultStates[0], $next: resultStates.slice(1).reduceRight((next, value) => ({ ...value, $next: next }), null) } : null
84+
85+ // add linker into state.raw
86+ const firstPacket = resultStates ?. [ 0 ]
87+ if ( resultStates . length ) {
88+ const nextPacket = resultStates . slice ( 1 ) . reduceRight ( ( next , value ) => {
89+ // return { ...value, $next: next }
90+ Object . assign ( value . raw , { $next : next } )
91+ return value
92+ } , null )
93+
94+ Object . assign ( firstPacket . raw , { $next : nextPacket } )
95+ }
96+
7697 Object . assign ( state , firstPacket )
7798 }
7899 }
@@ -120,7 +141,9 @@ export default class unrealengine3lan extends CoreLAN {
120141 parsePacket ( buffer ) {
121142 // create default empty state
122143 const state = this . createState ( )
123- Object . assign ( state , UE3 . EmptyPayloadData )
144+
145+ // create empty game settings
146+ const OnlineGameSettings = { ...UE3 . EmptyPayloadData }
124147
125148 const fullReader = this . reader ( buffer )
126149 const packetVersion = fullReader . uint ( 1 )
@@ -136,30 +159,31 @@ export default class unrealengine3lan extends CoreLAN {
136159 state . raw . hostaddress = ipStr
137160 state . raw . hostport = port
138161
139- state . raw . NumOpenPublicConnections = reader . uint ( 4 )
140- state . raw . NumOpenPrivateConnections = reader . uint ( 4 )
141- state . raw . NumPublicConnections = reader . uint ( 4 )
142- state . raw . NumPrivateConnections = reader . uint ( 4 )
162+ OnlineGameSettings . NumOpenPrivateConnections = 1
163+ OnlineGameSettings . NumOpenPublicConnections = reader . uint ( 4 )
164+ OnlineGameSettings . NumOpenPrivateConnections = reader . uint ( 4 )
165+ OnlineGameSettings . NumPublicConnections = reader . uint ( 4 )
166+ OnlineGameSettings . NumPrivateConnections = reader . uint ( 4 )
143167
144168 // new packets seem to have an additional bool/byte field,
145169 // flags generally consist of 8 1-byte/bool values
146- state . raw . bShouldAdvertise = reader . uint ( 1 ) === 1
147- state . raw . bIsLanMatch = reader . uint ( 1 ) === 1
148- state . raw . bUsesStats = reader . uint ( 1 ) === 1
149- state . raw . bAllowJoinInProgress = reader . uint ( 1 ) === 1
150- state . raw . bAllowInvites = reader . uint ( 1 ) === 1
151- state . raw . bUsesPresence = reader . uint ( 1 ) === 1
152- state . raw . bAllowJoinViaPresence = reader . uint ( 1 ) === 1
153- state . raw . bUsesArbitration = reader . uint ( 1 ) === 1
170+ OnlineGameSettings . bShouldAdvertise = reader . uint ( 1 ) === 1
171+ OnlineGameSettings . bIsLanMatch = reader . uint ( 1 ) === 1
172+ OnlineGameSettings . bUsesStats = reader . uint ( 1 ) === 1
173+ OnlineGameSettings . bAllowJoinInProgress = reader . uint ( 1 ) === 1
174+ OnlineGameSettings . bAllowInvites = reader . uint ( 1 ) === 1
175+ OnlineGameSettings . bUsesPresence = reader . uint ( 1 ) === 1
176+ OnlineGameSettings . bAllowJoinViaPresence = reader . uint ( 1 ) === 1
177+ OnlineGameSettings . bUsesArbitration = reader . uint ( 1 ) === 1
154178 if ( packetVersion >= 5 ) {
155179 // read additional flag for newer packets
156- state . raw . bAntiCheatProtected = reader . uint ( 1 ) === 1
180+ OnlineGameSettings . bAntiCheatProtected = reader . uint ( 1 ) === 1
157181 }
158182
159183 // Read the owning player id
160- state . raw . OwningPlayerId = unrealengine3 . readUniqueNetId ( reader )
184+ OnlineGameSettings . OwningPlayerId = unrealengine3 . readUniqueNetId ( reader )
161185 // Read the owning player name
162- state . raw . OwningPlayerName = unrealengine3 . readString ( reader )
186+ OnlineGameSettings . OwningPlayerName = unrealengine3 . readString ( reader )
163187
164188 // properties from the advertised settings
165189 const localizedProperties = [ ]
@@ -194,8 +218,8 @@ export default class unrealengine3lan extends CoreLAN {
194218 }
195219
196220 // Turn all that raw state into something useful
221+ state . raw . session = OnlineGameSettings
197222 this . populateProperties ( state )
198- // DEBUG: delete state.raw
199223
200224 return state
201225 }
@@ -205,46 +229,45 @@ export default class unrealengine3lan extends CoreLAN {
205229 * @param {Object } state Parsed data
206230 */
207231 populateProperties ( state ) {
232+ const { session } = state . raw
233+
208234 // pass raw data
209235 state . gameHost = state . raw . hostaddress
210236 state . gamePort = state . raw . hostport
211237
212- state . name = state . raw . OwningPlayerName
213- state . maxplayers = state . raw . NumOpenPublicConnections
238+ session . TotalOpenConnections = ( session ?. NumOpenPublicConnections || 0 ) + ( session ?. NumOpenPrivateConnections || 0 )
239+ session . TotalConnections = ( session ?. NumPublicConnections || 0 ) + ( session ?. NumPrivateConnections || 0 )
214240
215- state . NumOpenPublicConnections = state . raw . NumOpenPublicConnections
216- state . NumOpenPrivateConnections = state . raw . NumOpenPrivateConnections
217- state . NumPublicConnections = state . raw . NumPublicConnections
218- state . NumPrivateConnections = state . raw . NumPrivateConnections
241+ state . name = session ?. OwningPlayerName
242+ state . raw . maxplayers = ( session . TotalConnections ) . toString ( )
243+ state . raw . numplayers = ( session . TotalConnections - session . TotalOpenConnections ) . toString ( )
219244
220- state . bShouldAdvertise = state . raw . bShouldAdvertise
221- state . bIsLanMatch = state . raw . bIsLanMatch
222- state . bUsesStats = state . raw . bUsesStats
223- state . bAllowJoinInProgress = state . raw . bAllowJoinInProgress
224- state . bAllowInvites = state . raw . bAllowInvites
225- state . bUsesPresence = state . raw . bUsesPresence
226- state . bAllowJoinViaPresence = state . raw . bAllowJoinViaPresence
227- state . bUsesArbitration = state . raw . bUsesArbitration
228- state . bAntiCheatProtected = state . raw . bAntiCheatProtected
245+ // pass specific session fields
229246
230- state . OwningPlayerId = Buffer . from ( state . raw . OwningPlayerId ) . toString ( 'hex' )
231- state . OwningPlayerName = state . raw . OwningPlayerName
247+ // replace uniqueid with stringified id
248+ session . OwningPlayerId = unrealengine3 . UniqueNetIdToString ( session ?. OwningPlayerId )
249+ state . raw . OwningPlayerId = session . OwningPlayerId
250+ state . raw . OwningPlayerName = session . OwningPlayerName
251+ state . raw . bUsesStats = anyToString ( session . bUsesStats || false )
252+ state . raw . bIsDedicated = anyToString ( session . bIsDedicated || false )
253+ state . raw . NumPublicConnections = anyToString ( session . NumPublicConnections )
232254
233255 // manually transform serialized properties into known structure
234256 const props = state . raw . Properties ?. reduce ( ( acc , prop ) => {
235- acc [ `p${ prop . PropertyId } ` ] = prop . Data . ValueRaw
257+ acc [ `p${ prop . PropertyId } ` ] = String ( prop . Data . ValueRaw ) // force string
236258 return acc
237259 } , { } )
238260
239261 // manually transform serialized localized properties into known structure
240262 const propsLocalized = state . raw . LocalizedProperties ?. reduce ( ( acc , prop ) => {
241- acc [ `s${ prop . Id } ` ] = prop . ValueIndex // TOOD: find actual value
263+ acc [ `s${ prop . Id } ` ] = String ( prop . ValueIndex ) // force string
242264 return acc
243265 } , { } )
244266
245267 // translate properties
246- state . raw = { ...state . raw , ...props , ...propsLocalized }
247- this . translate ( state . raw , this . translateMap )
268+ const stateRaw = { ...state . raw , ...props , ...propsLocalized }
269+ Object . assign ( state . raw , stateRaw )
270+ this . translate ( state . raw , this . translateMap ) // Note: Legacy handling of query values
248271
249272 // Turn all that raw state into something useful
250273 unrealengine3 . staticPopulateProperties ( state )
0 commit comments