psforever / psf-loginserver Goto Github PK
View Code? Open in Web Editor NEWEmulated PlanetSide 1 world and login server by the PSForever project.
Home Page: https://psforever.net
License: GNU General Public License v3.0
Emulated PlanetSide 1 world and login server by the PSForever project.
Home Page: https://psforever.net
License: GNU General Public License v3.0
Facility Status UI for surface Bases, their Flag Icons, and NTU charge will not properly update within a game session.
The current logging scheme isn't setup to mesh well with actors, actor systems, or MDC data.
Here are some links to help:
http://code.hootsuite.com/logging-contextual-info-in-an-asynchronous-scala-application/
http://doc.akka.io/docs/akka/current/java/logging.html
https://github.com/Log4s/log4s
https://yanns.github.io/blog/2014/05/04/slf4j-mapped-diagnostic-context-mdc-with-play-framework/
/squad is currently global for team, despite Squads being implemented. We use /platoon on Test Live 51200 for Global to Team.
/platoon is not implemented for the proper Global to Team.
/broadcast is the default message, currently. On live, it was Local. The expected behavior for Master is currently Squad or Platoon, preferably Platoon, as the Global to Team chat.
Voice chat text is issued twice clientside.
This is the current setup for 51200 and it's pretty important to move this to Master.
The current implementation is a hack. These packets are treated specially in the PS client (they are "slots" for reliable subpackets). The client only has 8 slots and the way it selects between them is strange.
Additionally, the server does not handle this packet type at all. The client will disconnect without this being handled.
LoginRespMessage needs more reverse engineering to figure out how to correctly pass a token value to a client for storage. Currently, the client will not forward the hardcoded token in the LoginSessionActor
Check out https://travis-ci.org/psforever/PSF-LoginServer/builds/152131655 and https://travis-ci.org/psforever/PSF-LoginServer/builds/152123698
I have noticed this hang when testing locally as well. It's something to do with the native PSCrypto library (but not the library code itself). Can't reproduce at the moment
When sending the below
val response = ConnectToWorldMessage(serverName, serverAddress.getHostString, serverAddress.getPort)
sendResponse(PacketCoding.CreateGamePacket(0, response))
sendResponse(DropSession(sessionId, "user transferring to world"))
combined with this
def removeSessionById(id : Long, reason : String, graceful : Boolean) : Unit = {
...
if(graceful) {
for(i <- 0 to 5) {
session.send(closePacket)
}
}
// kill all session specific actors
session.dropSession(graceful)
...
}
Can cause the client to fail when connecting to the world. Either we dont do this gracefully or we add a delay
2016-07-31 18:50:59,704 INFO "" login-session-router - New session ID=45 from /X:54346
2016-07-31 18:51:00,164 INFO "sessionId=45" LoginSessionActor - New login UN:ASDF PW:Some(ASDF). Client Version: 3.15.84, Dec 2 2009
2016-07-31 18:51:00,401 INFO "" world-session-router - New session ID=64 from /X:54345
2016-07-31 18:51:01,482 INFO "sessionId=45" LoginSessionActor - New login UN:ASDF PW:Some(ASDF). Client Version: 3.15.84, Dec 2 2009
2016-07-31 18:51:01,482 INFO "sessionId=45" LoginSessionActor - Connect to world request for 'PSForever'
2016-07-31 18:51:01,482 INFO "sessionId=45" login-session-router - Dropping session ID=45 (reason: user transferring to world)
2016-07-31 18:51:02,181 INFO "sourceThread=PsLogin-akka.actor.default-dispatcher-4, akkaSource=akka://PsLogin/user/login-udp-endpoint/login-session-router/login-session-45, sourceActorSystem=PsLogin, akkaTimestamp=16:51:02.179UTC" akka.actor.LocalActorRef - Message [LoginSessionActor$UpdateServerList] from Actor[akka://PsLogin/user/login-udp-endpoint/login-session-router/login-session-45#-1487728806] to Actor[akka://PsLogin/user/login-udp-endpoint/login-session-router/login-session-45#-1487728806] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
2016-07-31 18:51:02,765 DEBUG "" login-session-router - Session(45, 954)
2016-07-31 18:51:02,765 DEBUG "" world-session-router - Session(64, 18)
2016-07-31 18:51:02,765 DEBUG "" login-session-router - Reaped session ID=45
2016-07-31 18:51:07,765 DEBUG "" world-session-router - Session(64, 36)
2016-07-31 18:51:10,104 INFO "" login-session-router - New session ID=46 from /X:54346
2016-07-31 18:51:10,105 ERROR "sessionId=46" CryptoSessionActor - Unexpected packet type EncryptedPacket(3,ByteVector(64 bytes, 0xf0603c68661fe8c7fb763576da764333fb763576da7643337d509584c0caadf043a470a8dbda3fbeb9f813e8de63c01d883a6e43af64c87e7d509584c0caadf0)) in state NewClient
2016-07-31 18:51:12,765 DEBUG "" world-session-router - Session(64, 54)
2016-07-31 18:51:12,765 DEBUG "" login-session-router - Session(46, 68)
2016-07-31 18:51:17,765 DEBUG "" login-session-router - Session(46, 68)
2016-07-31 18:51:17,765 DEBUG "" world-session-router - Session(64, 72)
2016-07-31 18:51:17,765 INFO "" login-session-router - Dropping session ID=46 (reason: session timed out (outbound))
2016-07-31 18:51:22,766 DEBUG "" world-session-router - Session(64, 90)
2016-07-31 18:51:22,766 DEBUG "" login-session-router - Session(46, 80)
2016-07-31 18:51:22,766 DEBUG "" login-session-router - Reaped session ID=46
2016-07-31 18:51:27,765 DEBUG "" world-session-router - Session(64, 108)
2016-07-31 18:51:30,135 INFO "" login-session-router - New session ID=47 from /X:54346
2016-07-31 18:51:30,135 ERROR "sessionId=47" CryptoSessionActor - Unexpected packet type EncryptedPacket(5,ByteVector(64 bytes, 0x68b300328436490dfb763576da764333fb763576da7643334cfbe2e844ef1969d6ddee09f3f196a72a05b601e766571e0f32b9dad9b89d9d7d509584c0caadf0)) in state NewClient
Currently we have no support for placed or triggered CE. This was a core aspect of planetside gameplay
SessionRouter or some session specific parent needs to watch child Actors for death events and appropriately restart them.
2016-05-01 23:28:40,326 ERROR [PsLogin-akka.actor.default-dispatcher-10 sessionId=none] akka.actor.OneForOneStrategy - MultiPacket(Vector(ByteVector(62 bytes, 0x0009000403895053466f72657665720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000), ByteVector(62 bytes, 0x0009000203895053466f72657665720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000))) (of class psforever.net.MultiPacket)
scala.MatchError: MultiPacket(Vector(ByteVector(62 bytes, 0x0009000403895053466f72657665720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000), ByteVector(62 bytes, 0x0009000203895053466f72657665720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000))) (of class psforever.net.MultiPacket)
at LoginSessionActor.handleControlPkt(LoginSessionActor.scala:37)
at LoginSessionActor$$anonfun$Started$1.applyOrElse(LoginSessionActor.scala:30)
at akka.actor.Actor$class.aroundReceive(Actor.scala:482)
at LoginSessionActor.akka$actor$MDCContextAware$$super$aroundReceive(LoginSessionActor.scala:9)
at akka.actor.MDCContextAware$class.aroundReceive(MDCContextAware.scala:25)
at LoginSessionActor.aroundReceive(LoginSessionActor.scala:9)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
2016-05-01 23:28:41,148 ERROR [PsLogin-akka.actor.default-dispatcher-31 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x03)
2016-05-01 23:28:42,041 ERROR [PsLogin-akka.actor.default-dispatcher-30 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x01)
2016-05-01 23:28:42,773 ERROR [PsLogin-akka.actor.default-dispatcher-31 sessionId=none] LoginSessionActor - Unknown message
2016-05-01 23:28:43,743 ERROR [PsLogin-akka.actor.default-dispatcher-31 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x04)
2016-05-01 23:28:43,885 ERROR [PsLogin-akka.actor.default-dispatcher-33 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x02)
2016-05-01 23:28:44,837 ERROR [PsLogin-akka.actor.default-dispatcher-33 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x03)
2016-05-01 23:28:45,851 ERROR [PsLogin-akka.actor.default-dispatcher-22 sessionId=2] CryptoSessionActor - Failed to decode encrypted packet: Failed to parse control packet 0x09: unknown: expected constant BitVector(8 bits, 0x00) but got BitVector(8 bits, 0x01)
2016-05-01 23:28:46,715 INFO [PsLogin-akka.actor.default-dispatcher-33 sessionId=none] akka.actor.LocalActorRef - Message [psforever.net.ControlPacket] from Actor[akka://PsLogin/user/session-router/crypto-session2#1836272772] to Actor[akka://PsLogin/user/session-router/login-session2#-143057463] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
In order for people to actually have a chance at contributing to this project, good documentation will be required. Scala is a hard enough barrier to entry as is. Bad documentation cannot be afforded.
Learn how to generate ScalaDocs: http://alvinalexander.com/scala/how-to-generate-scala-documentation-scaladoc-command-examples
Beyond ScalaDocs, higher level architectural diagrams will be required as this game server is Actor/Service oriented and will not be sharing memory between Actors. This is hard enough for me to figure out. I can't imagine the nightmare it would be for someone else new to this paradigm.
Generators only work at Anguta on Ceryshen.
Here's a cool powershell example that works: https://stackoverflow.com/questions/34247757/why-is-the-external-ip-not-returned-from-a-upnp-getexternalipaddress-query-using
This issue was noticed when trying to host a game server behind a router. A simpler way to handle this would be to provide a configuration file where people could provide a public IP or domain name.
But hey, one can dream, right?
Not sure why this happens, but it occurs randomly when zoning. Seems like a race condition when switching zones.
2020-01-12 01:27:09,338 INFO "sessionId=10" WorldSessionActor - Load in zone z4 at position Vector3(3059.0,2144.0,70.0) in 0 seconds
2020-01-12 01:27:09,338 INFO "sessionId=10" WorldSessionActor - Chat: ChatMsg(CMT_ZONE,true,,z4,None)
2020-01-12 01:27:09,338 INFO "" WorldSessionActor - Player asdf will respawn
2020-01-12 01:27:09,338 INFO "" WorldSessionActor - Setting up combat engineering UI ...
2020-01-12 01:27:09,339 ERROR "sourceThread=PsLogin-akka.actor.default-dispatcher-12, akkaSource=akka://PsLogin/user/service/cluster/z4-actor/z4-players, sourceActorSystem=PsLogin, akkaTimestamp=01:27:09.339UTC" akka.actor.OneForOneStrategy - actor name [asdf_3317] is not unique!
akka.actor.InvalidActorNameException: actor name [asdf_3317] is not unique!
at akka.actor.dungeon.ChildrenContainer$NormalChildrenContainer.reserve(ChildrenContainer.scala:129)
at akka.actor.dungeon.Children$class.reserveChild(Children.scala:130)
at akka.actor.ActorCell.reserveChild(ActorCell.scala:374)
at akka.actor.dungeon.Children$class.makeChild(Children.scala:268)
at akka.actor.dungeon.Children$class.actorOf(Children.scala:42)
at akka.actor.ActorCell.actorOf(ActorCell.scala:374)
at net.psforever.objects.zones.ZonePopulationActor$$anonfun$receive$1.applyOrElse(ZonePopulationActor.scala:48)
at akka.actor.Actor$class.aroundReceive(Actor.scala:482)
at net.psforever.objects.zones.ZonePopulationActor.aroundReceive(ZonePopulationActor.scala:21)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
2020-01-12 01:27:09,750 INFO "sessionId=10" WorldSessionActor - CreateShortcutMessage: CreateShortcutMessage(ValidPlanetSideGUID(0),1,0,true,Some(Shortcut(0,medkit,,)))
2020-01-12 01:27:09,750 INFO "sessionId=10" WorldSessionActor - AvatarFirstTimeEvent: AvatarFirstTimeEventMessage(ValidPlanetSideGUID(3317),ValidPlanetSideGUID(6864),1,used_pulsar)
``
Log files can get very big if the server is running for a while. Change config/logback.xml
to incorporate rolling files
https://stackify.com/logging-logback/
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>3MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>[%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
Requires #278 to have been partially addressed to lower the JVM bytecode size. There is no fix besides refactoring this file.
[error] /home/travis/build/psforever/PSF-LoginServer/pslogin/src/main/scala/WorldSessionActor.scala:67: Could not write class WorldSessionActor because it exceeds JVM code size limits. Method handleGamePkt's code too large!
[error] class WorldSessionActor extends Actor with MDCContextAware {
[error] ^
[error] one error found
[error] (pslogin/compile:compileIncremental) Compilation failed
[error] Total time: 434 s, completed Oct 11, 2019 3:38:47 PM
Here is some context: https://github.com/scoverage/sbt-scoverage/issues/92
2020-01-12 00:12:59,448 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(355,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40113),Vector3(982.21094,1023.71094,100.875),0,446,63536,200,255,0,None)
2020-01-12 00:12:59,448 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(356,ValidPlanetSideGUID(40113),0,Some(HitInfo(Vector3(982.21094,1023.71094,100.875),Vector3(983.7422,1022.2344,100.515625),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:12:59,606 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(360,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40114),Vector3(982.2031,1023.71875,100.890625),0,486,63546,200,255,0,None)
2020-01-12 00:12:59,606 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(360,ValidPlanetSideGUID(40114),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.75,1022.2422,100.5),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:12:59,777 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(365,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40115),Vector3(982.2031,1023.71875,100.890625),0,462,63549,200,255,0,None)
2020-01-12 00:12:59,777 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(365,ValidPlanetSideGUID(40115),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.75,1022.2422,100.515625),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:12:59,886 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(370,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40116),Vector3(982.2031,1023.71875,100.890625),0,484,63574,200,255,0,None)
2020-01-12 00:12:59,886 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(370,ValidPlanetSideGUID(40116),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7656,1022.2578,100.5),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,108 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(375,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40117),Vector3(982.2031,1023.71875,100.890625),0,480,63569,200,255,0,None)
2020-01-12 00:13:00,108 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(375,ValidPlanetSideGUID(40117),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7578,1022.2578,100.5),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,262 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(380,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40118),Vector3(982.2031,1023.71875,100.890625),0,495,63594,200,255,0,None)
2020-01-12 00:13:00,262 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(380,ValidPlanetSideGUID(40118),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.78125,1022.2656,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,404 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(384,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40119),Vector3(982.2031,1023.71875,100.890625),0,495,63574,200,255,0,None)
2020-01-12 00:13:00,404 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(385,ValidPlanetSideGUID(40119),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7656,1022.2578,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,581 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(389,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40120),Vector3(982.2031,1023.71875,100.890625),0,489,63583,200,255,0,None)
2020-01-12 00:13:00,581 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(389,ValidPlanetSideGUID(40120),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.77344,1022.2578,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,756 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(394,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40121),Vector3(982.2031,1023.71875,100.890625),0,497,63567,200,255,0,None)
2020-01-12 00:13:00,757 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(394,ValidPlanetSideGUID(40121),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7578,1022.25,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:00,911 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(399,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40122),Vector3(982.2031,1023.71875,100.890625),0,483,63568,200,255,0,None)
2020-01-12 00:13:00,911 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(399,ValidPlanetSideGUID(40122),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7578,1022.2578,100.5),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:01,073 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(404,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40123),Vector3(982.2031,1023.71875,100.890625),0,490,63598,200,255,0,None)
2020-01-12 00:13:01,073 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(404,ValidPlanetSideGUID(40123),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.78906,1022.2656,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:01,151 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(409,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40124),Vector3(982.2031,1023.71875,100.890625),0,489,63560,200,255,0,None)
2020-01-12 00:13:01,248 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(409,ValidPlanetSideGUID(40124),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.7578,1022.25,100.484375),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:01,249 DEBUG "" services.support.SupportActor - a target submitted: Entry(net.psforever.objects.SensorDeployable@13e8b19d,Zones$$anon$14@12bb4822,0)
2020-01-12 00:13:01,267 DEBUG "" services.support.SupportActor - no tasks matching the targets List(net.psforever.objects.SensorDeployable@13e8b19d) have been cleared
2020-01-12 00:13:01,371 INFO "sessionId=7" WorldSessionActor - WeaponFire: WeaponFireMessage(414,ValidPlanetSideGUID(9829),ValidPlanetSideGUID(40100),Vector3(982.2031,1023.71875,100.890625),0,481,63550,200,255,0,None)
2020-01-12 00:13:01,371 INFO "sessionId=7" WorldSessionActor - Hit: HitMessage(414,ValidPlanetSideGUID(40100),0,Some(HitInfo(Vector3(982.2031,1023.71875,100.890625),Vector3(983.75,1022.2422,100.5),Some(ValidPlanetSideGUID(7460)))),true,false,None)
2020-01-12 00:13:01,376 ERROR "sourceThread=PsLogin-akka.actor.default-dispatcher-14, akkaSource=akka://PsLogin/user/world-udp-endpoint/world-session-router/world-session-7, sourceActorSystem=PsLogin, akkaTimestamp=00:13:01.374UTC" akka.actor.OneForOneStrategy - null
java.lang.NullPointerException: null
at WorldSessionActor.HandleDealingDamage(WorldSessionActor.scala:8712)
at WorldSessionActor.handleGamePkt(WorldSessionActor.scala:5661)
at WorldSessionActor$$anonfun$Started$1.applyOrElse(WorldSessionActor.scala:359)
at scala.PartialFunction$OrElse.applyOrElse(PartialFunction.scala:171)
at akka.actor.Actor$class.aroundReceive(Actor.scala:482)
at WorldSessionActor.akka$actor$MDCContextAware$$super$aroundReceive(WorldSessionActor.scala:80)
at akka.actor.MDCContextAware$class.aroundReceive(MDCContextAware.scala:23)
at WorldSessionActor.aroundReceive(WorldSessionActor.scala:80)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
```
Using a Voice Macro results in a double Chat Text message for the corresponding Voice Macro.
Having done some packet diving, I've discovered at least two packets that pass ASCII in a wide character format, but do not have the length prefacing the string directly. We have no prepared encoding or decoding for this kind of data as they all assume the first byte or pair of bytes are string length, and this means we can not build packet handling logic. The straightforward aspect of the packet handling also doesn't leave much room for interjection.
For example, a DestroyDisplayMessage packet looks like this:
81 87
41006E00670065006C006C006F00
35BC D801 8F 20 19207 0A 0
48004D00460049004300
B18E D901 00
There are two character strings here. For the first string, 87
is the proper length (well, 7 is) so the whole thing can be decoded normally. For the second string, however, the length is actually encoded in the 0A
in front of the lone 0
as twice the length of the string (5 x 2 = 10, or 0A
; modifying it produces predictable results). The number format is incorrect, and the buffering 0
just throws the whole thing off.
In addition, passing DestroyDisplayMessage with the correct form of the encoded wide character string to the client - 8548004D00460049004300
- causes the client to display illegible pictograms in place of the string.
Here's an example of a DamageFeedbackMessage:
7B 76 14
48004D00460049004300
86 03 90 50 00 00 00
The wide character string is obvious but, this time, the only suggestions of the size exists as high order bits towards the far end of the data. Whether or not that's what it is, we can't deal with it. (A five letter wide character string also has twenty nibbles and 14
is 20 ... I just made that up on the spot.)
PSPacket.scala contains a bunch of messages. These should be divided up in to individual files like VNLWorldStatusMessage.scala.
Nothing happens when attempting to use a Medkit. Master server (51000).
PlanetSide runs on top of UDP. UDP is not reliable.
We want a nice way for the user to send messages to a client with some reliability guarantees without worrying about how to construct a SlottedMetaPacket. We should completely abstract away from fragmentation issues, packet reordering, and packet loss.
Code needs to be written to correctly these cases if we are going to have a reliable server.
This is related to #3
TR can only get to Solsar from Sanctuary, and capturing Solsar does not grant you additional links.
NC has no functioning Warpgates, they all "one-way" instantly warp you back to Sanctuary Spawn
VS can only get to Ceryshen from Sanctuary
I think the current Test Live (51200) does something special to handle this. @SouNourS would know.
Players can receive Enemy Squad Chat Messages from Tactical Voice macros when an enemy player who is in a Squad uses them.
When attempting to Revive a member of your Empire, the bar often only fills a small amount, but is constantly reset, and the player never gets revived.
It may be nice to have a Dockerfile so people can easily build the server, will probably make it easier for people to test too! I can have a stab at this over the next few days if you think it would be useful? :)
This project is supposed to be the login server only, but there are world server components.
Fix this to avoid confusion.
Travis CI is broken because we don't have a way to get the pscrypto library in to the build environment.
This isn't just a problem for Travis -- no one will be able to develop without this library.
It would be nice when the README.md would contain information how to get in contact with the dev team (e.g. Discord or the website).
This issue is also relevant for other repositories like the world server.
Players cannot create accounts in-game on the Master CI server port 51000.
When attempting to decode this appears
Failed to decode encrypted packet: Failed to parse control packet 0x07: Could not find a marshaller for control packet Unknown7
Failed to decode inner packet Failed to parse game packet 0x01: credential_choice: US-ASCII cannot decode string from '0x484f35366e51706c6c73705046395632000000000000000000b8060390b80603'
Failed to decode inner packet Failed to parse game packet 0x01: credential_choice: US-ASCII cannot decode string from '0x484f35366e51706c6c73705046395632000000000000000000b8060390b80603'
Looks like it could have something to do with the fixedSizedByte
combinator in scodec (see
PSF-LoginServer/common/src/main/scala/psforever/net/PSPacket.scala
Lines 141 to 145 in 30a94a0
Currently there is a lot of boilerplate required to describe a new packet (names used in multiple places) and a lot of cross linking required between decoding and encoding. Maybe there isn't a way to avoid this but at the very least a way to template this would be awesome.
Thoughts below.
HotSpotUpdateMessage is the packet that creates those explosions on the continental map that indicate where combat took place recently. While I think I understand how the packet is composed, and could otherwise write it, there's a bit of a snag with the decoding/encoding. The packet stores hotspot data as a list preceded by its size - scodec otherwise knows how to handle that - but the size is padded from the actual list by four bits. This makes the contents of the list byte-aligned. Scodec doesn't know how to handle that with its standard function listOfN
. While it does come with a stock sizedList
function that can handle manually provided sizes, the size has to be a non-negative Integer literal. if I could get there from a variable gotten via >>:~
from the same decoding process, that would be good, but I don't know how to do that. The function is not convinced.
I would like a function that works like listOfN
, excepting that it ignores padding, but I can not repurpose the existing methods myself. listOfN
handles List extraction by passing the buck off to a function called narrow
; narrow
does the same to exmap
; and, the result of this chain is a Tuple that contains both the size and the already-extracted List data. The whole process is a bit spooky to walk through. The approach as with aligned wide-character Strings (issue #67) also might not be possible here.
Here's a sample: first a packet with no entries, a packet with one entry, then that same packets with the nibbles spaced by field.
9F 05 00 10 00
9F 05 00 10 10 00 2E 90 01 45 80 00 00
9F 0500 1 00 (0)
9F 0500 1 01
000 2E9 00 145 80000 (0)
That weird 0 is the four bits of padding, with the size of the list as the byte before it and everything after it a part of the entry. The padding also can not be made a part of the entry to eliminate it because each entry begins right after the previous, with the first byte starting in place of the former trailing nibble.
9F 05 00 10 20 00 D0 70 08 CA 80 00 00 0B EA 00 4C 48 00 00
9F 0500 1 02
000D07008CA80000 00BEA004C480000
Some candidates:
It seems like NoSQL / document based DB would allow me to move fast and use plain ol' JSON. A SQL based DB would probably be overkill unless that's preferred for account records. More transient data, such as game state may benefit more from a NoSQL solution.
2019-12-15 21:27:01,901 INFO "sessionId=108" WorldSessionActor - DismountVehicleMsg: DismountVehicleMsg(PlanetSideGUID(5113),Normal,false)
2019-12-15 21:27:01,901 WARN "" WorldSessionActor - DismountVehicleMsg: TR awildchord i3-5113 100/100 50/50 attempted to dismount ams, owned by Some(PlanetSideGUID(5113)): (3000/3000)(0/601) (1)'s seat 0, but was not allowed
I was allowed to enter but not leave ๐ฌ
It's been said for a while at this point, but WorldSessionActor needs to be broken up into smaller files. It has grown to nearly 10K lines of Scala, which is dense as it is. Maintaining and understanding this file is likely next to impossible for new developers. It's so big that TravisCI fails to compile it with code coverage enabled!
Nearly all of the player business logic for PlanetSide is in this single file. Let's start to logically divide this up into smaller sub-files.
Resulted in an "Unknown Login Error" message during Login Progress.
See debug log: pslogin-debug_2019-10-11_20-45-09.log
[ERROR] CryptoSessionActor - Could not decode packet in state CryptoSetupFinishing: unmarshal_crypto_packet/obj_type?: expected constant BitVector(8 bits, 0x10) but got BitVector(8 bits, 0x01) [ERROR] CryptoSessionActor - Could not decode packet in state CryptoSetupFinishing: unmarshal_crypto_packet/obj_type?: expected constant BitVector(8 bits, 0x10) but got BitVector(8 bits, 0x01) [ERROR] CryptoSessionActor - Could not decode packet in state CryptoSetupFinishing: unmarshal_crypto_packet/obj_type?: expected constant BitVector(8 bits, 0x10) but got BitVector(8 bits, 0x01)
Geowarps do not warp players to Cavern zones
PlanetSide packet decoding is so next-gen that string decoding can occur on non-byte aligned boundaries. Scodec doesnt like this (especially since codecs are structural, not dynamic in nature) and is not able to decode a second world:
This reason this occurs is that the end of the world record within the VNLWorldStatusMessage is not byte aligned. On the second go around for a new world record, the bitvector is misaligned. Within the PlanetSide client there is an alignment operation performed right after the length of the following string is read. This is okay, but the VNLWorldStatusMessage isn't written for a misalignment. This leads to the behavior that the first entry decodes fine, but not the second. The only way I see to handle this is to somehow communicate to the encodedString
codec that the input stream is misaligned. But of course, scodec is pure functional and PlanetSide decoding is imperative (meaning the decoding class has access to the current position in the overall bitstream).
Scodec may need to be modified or something completely custom may have to be done for this case. I would prefer to have a general solution as this issue is definitely going to come up again in a different way.
When characters zone, the client often crashes to desktop during the Loading Screen.
Current Result: The game client will commonly crash to desktop during zone transfer.
Expected Result: The game client should never crash during zone transfer.
Reproduction Steps:
We have settled on MariaDB for our database. This is essentially feature equivalent with MySQL but more open source (different philosophy).
Now we need
See title.
I cannot for the life of me, even as the author, reliably write code that deals with unwrapping packet containers in to inner packets. The naming scheme must change.
Also, the decision to handle packet sequence numbers in the containers was not well thought out as more reverse engineering had to be done in order to figure out how they were actually being used. Now I know once encryption is enabled that they are used for game and control packets. Control packet containers do not have a field for sequence numbers. This is because the first packets that are sent are control packets, but they are NOT sequences.
This maybe should be rethought as it is just not working as is.
Implants are never initialized for characters.
We either need to circumvent the timers for now like Live, or make Implants activate after timers.
Comment extracted from PR #152 :
"[In regards to working with SlottedMetaPacket
s,] after reviewing how packets are handled, I determined the best place to intercept packets as they left the server was CyptoSessionActor
. They leave WorldSessionActor
to CSA
as packets and they leave CSA
to SessionRouter
as bit/byte vectors. If I were to handle them at the WSA
level, I'd be testing the packet length by prematurely encoding them and, if it was a sufficient length for maximum transmission unit restrictions, I'd be stuck. Since I wouldn't be manipulating them any further, either I would have to send out the original packet and have it encoded a second time later or I would send out my encoded data and completely bypass checks that were written into CSA
. Hoisting [this logic] out of CSA
means that the same complicated procedures would have to be repeated in LoginSessionActor
as well as anything else we build on top of CSA
.
"...
"SlottedMetaPacket
and MultiPacket
/MultiPacketEx
need to change. That's my opinion. The data that is supposed to be put in them is a 'stream', but that inconveniences our ability to construct them since a 'stream' is further along in our process of encoding than we allow input and control. We lack the ability of feeding multiple packets into Multi
, for example, because our normal procedure works one packet at a time. It's unnecessarily restricting and suggests the doubling of work. We extract and decode the data from these Control packets whenever we need it, and just once, because, until we process the packet, it's just a Control
packet with a 'stream of data.'"
!ntu
!hack
!list zone
Cave !hack
Bases/!warp
locations
When running the scripts generated by sbt-pack on Linux, the inferred classpath does not include the lib/ dir or any other directory. This means that it is impossible to load any .SO object and therefore the server won't run.
Improve the build.sbt pack settings to fix this: https://github.com/xerial/sbt-pack
After jacking an enemy Vehicle, the hacker will not see the vehicle ownership change clientside, despite changing for other players serverside.
Occurring on Master server (51000).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.