Closed Sheldon10095 closed 1 year ago
You probably need to implement ValidateAndRequestTicketWithCustomData. It us very similar to ValidateAndRequestTicketWithParam (which is already implemented here for SMB35). The only difference is the structure of the request and response parameters.
Can you implement this on your own?
You probably need to implement ValidateAndRequestTicketWithCustomData. It us very similar to ValidateAndRequestTicketWithParam (which is already implemented here for SMB35). The only difference is the structure of the request and response parameters.
Can you implement this on your own?
I'm currently trying, but I'm not sure I understand the errors I'm getting at the moment...
Can you implement this on your own?
Alright. I've got this added so far (code below), but I think I'm doing something wrong, since the game calls for RequestTicket afterwards. According to your docs, I don't think that should happen unless I'm sending it a bad ticket? I have a feeling that it's not too bad of an error. Do you by chance see something wrong with this? Perhaps I'm forgetting to encrypt something?
async def validate_and_request_ticket_with_custom_data(self, client, strUserName, oExtraData):
pid = next(self.pid)
key = secrets.token_bytes(16)
#Connection Data thing
url = common.StationURL(
scheme="prudps", address="0.0.0.1", port=1,
PID = SERVER_PID, CID = 1, type = 2,
sid = 2, stream = 10
)
conn_data = authentication.RVConnectionData()
conn_data.main_station = url
conn_data.special_protocols = []
conn_data.special_station = common.StationURL()
result = rmc.RMCResponse()
result.result = common.Result().success()
result.pid = pid
result.ticket = self.generate_ticket(pid, SERVER_PID, key, SERVER_KEY)
result.connection_data = conn_data
result.server_time = common.DateTime.now()
result.server_name = "S2GT - TEST"
result.source_key = key.hex()
return result
async def request_ticket(self, user_pid, server_pid, pSourceKey):
pid = next(self.pid)
key = secrets.token_bytes(16)
ticket = self.generate_ticket(pid, SERVER_PID, key, SERVER_KEY)
result = rmc.RMCResponse()
result.result = common.Result()
result.ticket = ticket
result.key = str(key)
return result
I'm not sure why it calls RequestTicket, because your validate_and_request_ticket_with_custom_data
method looks fine to me. The server_time
field doesn't exist, but that shouldn't cause any problems.
Your request_ticket
method is wrong. But even if it were correct it wouldn't work because the RequestTicket method should never have been called.
I should note that it doesn't seem like the console is sending any token to the server. It's just totally blank if I try to log it... Perhaps that's related?
Probably not. The token is blank because the ips patch disables NSO authentication.
Hmm alright... I'll try to figure out which function is causing the error then.
Also I forgot to mention, after implementing those two functions, the error the shown on the switch has changed to 2306-0502
again, and it displays the following message:
A server communication error has occurred. Please try again later.
My _QLOG hook is sending these to the logger as well. Not much info aha. Logs:
[Log Level 2]: It took 22 msec for nn::account::EnsureNetworkServiceAccountIdTokenCacheAsync()
[Log Level 2]: It took 239 msec for RendezVous::Login()
Wait sorry.
the ips patch disables NSO authentication.
This is wrong. You are not using my ips patch of course. I forgot we are talking about Splatoon 2 instead of SMB35 😅
Hold on a second.... It's giving me a different error now, If I change the "prudps" to "prudp" here:
url = common.StationURL(
scheme="prudp", address="0.0.0.1", port=1,
PID = SERVER_PID, CID = 1, type = 2,
sid = 2, stream = 10
)
The server is raising buffer overflow errors, though it isn't really telling me where exactly the root cause lies... 🤔
Ok- from what I've tested, when it's set to use "prudps", it calls RequestTicket.
But when it's set to just "prudp", it's raising a BufferOverflow exception in process_login_request
in when it tries to read data from the packet via a call to stream.buffer()
After having it print out the data in the packet, I've noticed that there's no data there. Basically it's trying to parse data that doesn't exist? Would you know what could be causing this? I can follow up with more info if needed.
It probably tries to log in anonymously if you use prudp instead of prudps, but the server only accepts connection requests with credentials. If you remove key=SERVER_KEY
from the line with rmc.serve_prudp
the server will only accept anonymous connections instead, which might work in your situation, but it is not the correct way to fix this.
I think it has to with the key in validate_and_request_ticket_with_custom_data
.
key = secrets.token_bytes(16)
If I change that to something like key = secrets.token_bytes(4)
, then I get error 2306-0304
, which is RendezVous::InvalidPassword
. When this happens, it doesn't call RequestTicket.
I have no idea. After all, it is only calling RequestTicket
since validate_and_request_ticket_with_custom_data
is incorrect. I just cannot figure out how to make it correct.
If you remove key=SERVER_KEY from the line with rmc.serve_prudp the server will only accept anonymous connections instead, which might work in your situation, but it is not the correct way to fix this.
That allowed me to pass the tutorial, but it failed at matchmaking of course because there was no PID sent. I hope I'm not asking too much 😅
I think it has to with the key in
validate_and_request_ticket_with_custom_data
.
I don't think so. The error code is probably misleading. For special user accounts, such as Administrator
, the key is derived from their password, but normal user accounts don't have a password. Instead, the server generates a random key and sends it to the client (this is the source_key
).
If you change the key size, the client probably fails to decrypt the ticket. It probably assumes that the key was derived from an incorrect password, because the decryption of the ticket should never fail for accounts that do not have a password.
it failed at matchmaking of course because there was no PID sent.
Yeah, that's because the client is connecting anonymously now :slightly_smiling_face:
So you either have to rewrite the match making server to work without PIDs, or fix your authentication server and use prudps.
I still don't see what's wrong with your ValidateAndRequestTicketWithCustomData
implementation... sorry I can't help.
Oh and I was also trying to do Splatoon 2 but not testfire and the server works when i start it locally but when i try to host it (on heroku) it has issues when i try to connect to it. Do you know what could be the problem or maybe you can recommend something else for hosting the server
Looks like your server is using SSL but the client is not. So, either remove SSL from your server or make sure that the client uses SSL.
Wait sorry I misread your comment.
I don't have any experience with heroku, but I would guess that there is some kind of load balancer or proxy in front of your server that forwards traffic to your Python server without TLS. It probably works if you disable TLS on your Python server.
Thanks it worked, but now there’s a new problem. When someone tries to create a room, it succeeds for some people like me but for others it is softlocked on the joining screen after which they for some reason call unregister gathering. This doesn’t happen for me, but when others try to join me they seem to send the join event (the timer in the lobby increases which happens when a person joins) and get added to the participants of it but they don’t join it on their side and get a game connection error (no error code). However they remain in the participants and when they try to join the lobby again they get RendezVous::AlreadyParticipatedGathering. I don’t know if this is game specific but if you could say anything about that it would be really helpful.
That is probably a problem in your match making implementation. I don't think I can help you with that, sorry. Also, Splatoon 2 doesn't use libeagle, so you can probably remove that from your code.
I’ve removed eagle and I’ve also observed that the error that prevented people from creating a lobby was connected to nat traversal. The game calls report_nat_properties and then secureserver send_report, where it gives a buffer overflow error when loading qbuffer from input stream (from the default lib’s handle_send_report). How can I implement changing nat properties when the game reports them to me (which it does when joining a match) and could the send_report be connected with the other disconnect which always happens when someone tries to join me? Also the other dc which happens when no one is using additional network settings happens because after the auto matchmake task finishes enl::PeerManagerCommon::isConnected returns 0 and goes to the error sequence. I don’t really have much experience with servers so some of the things I said might be stupid so sorry about that
Actually I figured out the issue. The game is trying to call replace_url, but calls send_report instead. How do I inform the new station url
I've also been trying with the regular Splatoon 2 and progress has been a bit easier, but I'm stuck on how I should set up the NAT server because it uses a different port (being 10025 or 10125 like you've mentioned in your docs). I've been getting the error 2618-0201
aka ResultNatCheckFailed
, which makes sense considering the game points to both nncs1-lp1.n.n.srv.nintendo.net
and nncs2-lp1.n.n.srv.nintendo.net
. So I've patched it to just point it to my local computer's IP while I test it. I'm just not sure how I should have the NATTraversalServer running compared to the other ones... any chance you could point me in the right direction?
NAT traversal is not the same as NAT check. The nncs servers use a completely different protocol and are not implemented by my Python package. You either need to implement them on your own or use Nintendo's servers.
You probably need to implement NATTraversalServer as well after solving your NAT check problems, but NATTraversalServer will not help you with NAT check.
Hey! This isn't exactly an issue with Super Mario Bros. 35
I was trying to adapt this custom server to the Splatoon 2 Global Testfire, and I managed to get the console to connect to my PC which is hosting the server, but then I realized that it was just giving me error
2306-0102
, (only when I had the server up of course). And yes, I have indeed changed the access key to match that of the testfire. Also, I've placed an image of the error screen at the bottom of this post.From what I can tell, there are a few needed funcs that aren't yet implemented... Is there any chance you could perhaps implement a few of them? I tried making some adjustments but I had no luck. I'm thinking its just a few authentication funcs. Maybe matchmaking eventually, but I'm not worried about that yet haha. I'm assuming that I should probably also mention that
handle_validate_and_request_ticket_with_custom_data
is where it's failing.If you need more info, lemme know!
Global Testfire Patches
Here are the patches that I've made ~~ Feel free to test them if you'd like.
//Set Custom Server URL @enabled 024FC706 "192.168.4.156:20000"
//nn::nex::JobAcquireNsaIdToken::StepWaitingForGetGameAuthentication(void)+9C -> Replace GetResult call with MOV X0, XZR @enabled 01132844 E0031FAA
//force branch at "CBZ W8, loc_7101132844" @enabled 01132924 08000014
Error Screen