From 75f4ef06606c8ce11dd10a7c45f30c4af6dc60c7 Mon Sep 17 00:00:00 2001 From: azurshinano Date: Sun, 21 Apr 2024 07:56:32 -0700 Subject: [PATCH] fix: Difference Between CN and EN regions 1. (CN)Fixed the problem of unable to complete the construction 2. (CN)Fixed the crash issue when viewing ship details 3. Recharge is temporarily disabled because according to the code we cannot easily complete in-game purchases as they are implemented through the sdk at the end. 4. Fixed the problem of some page crashes. The reason is that azurlane will check whether the data has been tampered with on certain occasions(not for priv server). 5. Implemented the function of checking whether the commander exists on the login page 6. (CN_JP_KR_TW)Implemented ServerInterconnection in azurlane code, which seems to be used to switch ios/android servers. This content has only been tested in CN_JP_KR_TW. --- answer/build_finish.go | 21 +++++++++------------ answer/charge_command_answer.go | 19 +++++++++++++++++++ answer/cheater_mark.go | 21 +++++++++++++++++++++ answer/forge_10803.go | 22 ++++++++++++++++++++++ answer/player_exist.go | 31 +++++++++++++++++++++++++++++++ answer/player_info.go | 2 +- answer/send_player_ship_count.go | 5 ++++- answer/update_packet.go | 2 +- connection/client.go | 32 ++++++++++++++++++++++++++++++++ consts/update_data.go | 11 +++++++++++ main.go | 26 ++++++++++++++++++++++++-- misc/game_update.go | 4 ++++ 12 files changed, 179 insertions(+), 17 deletions(-) create mode 100644 answer/charge_command_answer.go create mode 100644 answer/cheater_mark.go create mode 100644 answer/forge_10803.go create mode 100644 answer/player_exist.go diff --git a/answer/build_finish.go b/answer/build_finish.go index 3049bad..e4a2279 100644 --- a/answer/build_finish.go +++ b/answer/build_finish.go @@ -2,26 +2,23 @@ package answer import ( "github.com/ggmolly/belfast/connection" - "github.com/ggmolly/belfast/protobuf" "google.golang.org/protobuf/proto" ) -// XXX: i have no idea what this packet is for but this works, so... +// Get the corresponding template_id in the ship build list func BuildFinish(buffer *[]byte, client *connection.Client) (int, int, error) { - var data protobuf.CS_12043 - err := proto.Unmarshal(*buffer, &data) - if err != nil { - return 0, 12043, err + buildInfos := make([]*protobuf.BUILD_INFO, len(client.Commander.Builds)) + for i, work := range client.Commander.Builds { + buildInfos[i] = &protobuf.BUILD_INFO{ + Pos: proto.Uint32(uint32(i + 1)), + Tid: proto.Uint32(work.ShipID), + } } response := protobuf.SC_12044{ - InfoList: []*protobuf.BUILD_INFO{ // ??? - &protobuf.BUILD_INFO{ - Pos: proto.Uint32(1), - Tid: proto.Uint32(1), - }, - }, + InfoList: buildInfos, } + return client.SendMessage(12044, &response) } diff --git a/answer/charge_command_answer.go b/answer/charge_command_answer.go new file mode 100644 index 0000000..8bfeb2c --- /dev/null +++ b/answer/charge_command_answer.go @@ -0,0 +1,19 @@ +package answer + +import ( + "github.com/ggmolly/belfast/connection" + "github.com/ggmolly/belfast/protobuf" + "google.golang.org/protobuf/proto" +) + +func ChargeCommandAnswer(buffer *[]byte, client *connection.Client) (int, int, error) { + // Disable Charge + response := protobuf.SC_11502{ + Result: proto.Uint32(5002), + PayId: proto.String(""), + Url: proto.String(""), + OrderSign: proto.String(""), + } + + return client.SendMessage(11502, &response) +} diff --git a/answer/cheater_mark.go b/answer/cheater_mark.go new file mode 100644 index 0000000..6ce13e4 --- /dev/null +++ b/answer/cheater_mark.go @@ -0,0 +1,21 @@ +package answer + +import ( + "github.com/ggmolly/belfast/connection" + "github.com/ggmolly/belfast/protobuf" + "google.golang.org/protobuf/proto" +) + +func CheaterMark(buffer *[]byte, client *connection.Client) (int, int, error) { + var protoData protobuf.CS_10994 + err := proto.Unmarshal((*buffer), &protoData) + if err != nil { + return 0, 10995, err + } + + response := protobuf.SC_10995{ + Result: proto.Uint32(protoData.GetType()), + } + + return client.SendMessage(10995, &response) +} diff --git a/answer/forge_10803.go b/answer/forge_10803.go new file mode 100644 index 0000000..584056f --- /dev/null +++ b/answer/forge_10803.go @@ -0,0 +1,22 @@ +package answer + +import ( + "github.com/ggmolly/belfast/connection" + "github.com/ggmolly/belfast/consts" + "github.com/ggmolly/belfast/protobuf" + "google.golang.org/protobuf/proto" + "os" +) + +// In the Azurlane code, it is called ServerInterconnection, used to switch Android/iOS servers +func Forge_SC10803_CN_JP_KR_TW(buffer *[]byte, client *connection.Client) (int, int, error) { + belfastRegion := os.Getenv("AL_REGION") + response := protobuf.SC_10803_CN_JP_KR_TW{ + GatewayIp: proto.String(consts.RegionGateways[belfastRegion]), + GatewayPort: proto.Uint32(80), + ProxyIp: proto.String(consts.RegionProxies[belfastRegion]), + ProxyPort: proto.Uint32(20000), + } + + return client.SendMessage(10803, &response) +} diff --git a/answer/player_exist.go b/answer/player_exist.go new file mode 100644 index 0000000..ab514bf --- /dev/null +++ b/answer/player_exist.go @@ -0,0 +1,31 @@ +package answer + +import ( + "github.com/ggmolly/belfast/connection" + "github.com/ggmolly/belfast/protobuf" + "google.golang.org/protobuf/proto" +) + +// Check if an account exists on the game server +func PlayerExist(buffer *[]byte, client *connection.Client) (int, int, error) { + var protoData protobuf.CS_10026 + err := proto.Unmarshal((*buffer), &protoData) + if err != nil { + return 0, 10027, err + } + + response := protobuf.SC_10027{} + + err = client.GetCommander(protoData.GetAccountId()) + if err != nil { + // Player not found? + response.UserId = proto.Uint32(0) + response.Level = proto.Uint32(0) + } else { + // Even if the player is punished, we still return player information + response.UserId = proto.Uint32(client.Commander.CommanderID) + response.Level = proto.Uint32(uint32(client.Commander.Level)) + } + + return client.SendMessage(10027, &response) +} diff --git a/answer/player_info.go b/answer/player_info.go index cf177a9..3b4f213 100644 --- a/answer/player_info.go +++ b/answer/player_info.go @@ -43,7 +43,7 @@ func PlayerInfo(buffer *[]byte, client *connection.Client) (int, int, error) { CommanderBagMax: proto.Uint32(250), Display: &protobuf.DISPLAYINFO{ Icon: proto.Uint32(202124), // Should display Belfast's icon - Skin: proto.Uint32(202123), // Should display Belfast's default skin + Skin: proto.Uint32(202124), // Should display Belfast's default skin IconFrame: proto.Uint32(0), ChatFrame: proto.Uint32(0), IconTheme: proto.Uint32(0), diff --git a/answer/send_player_ship_count.go b/answer/send_player_ship_count.go index fcabdbc..7106848 100644 --- a/answer/send_player_ship_count.go +++ b/answer/send_player_ship_count.go @@ -1,6 +1,8 @@ package answer import ( + "github.com/ggmolly/belfast/consts" + "os" "time" "github.com/ggmolly/belfast/connection" @@ -10,9 +12,10 @@ import ( ) func SendPlayerShipCount(buffer *[]byte, client *connection.Client) (int, int, error) { + belfastRegion := os.Getenv("AL_REGION") answer := protobuf.SC_11002{ Timestamp: proto.Uint32(uint32(time.Now().Unix())), - Monday_0OclockTimestamp: proto.Uint32(1606114800), // 23/11/2020 08:00:00 + Monday_0OclockTimestamp: proto.Uint32(consts.Monday_0OclockTimestamps[belfastRegion]), ShipCount: proto.Uint32(uint32(len(client.Commander.Ships))), } client.Server.JoinRoom(client.Commander.RoomID, client) diff --git a/answer/update_packet.go b/answer/update_packet.go index 6093cb5..d51b339 100644 --- a/answer/update_packet.go +++ b/answer/update_packet.go @@ -50,7 +50,7 @@ func Forge_SC10801(buffer *[]byte, client *connection.Client) (int, int, error) ProxyPort: proto.Uint32(20000), IsTs: proto.Uint32(0), Timestamp: proto.Uint32(uint32(time.Now().Unix())), - Monday_0OclockTimestamp: proto.Uint32(consts.Monday_0OclockTimestamps[belfastRegion]), // // 23/11/2020 08:00:00 + Monday_0OclockTimestamp: proto.Uint32(consts.Monday_0OclockTimestamps[belfastRegion]), // wtf is this i don't even understand what monday_0oclock_timestamp is // who would even do such a thing diff --git a/connection/client.go b/connection/client.go index d7f4093..792e7ce 100644 --- a/connection/client.go +++ b/connection/client.go @@ -63,6 +63,38 @@ func (client *Client) CreateCommander(arg2 uint32) (uint32, error) { logger.LogEvent("Client", "CreateCommander", fmt.Sprintf("failed to give Belfast to account %d: %v", accountId, err), logger.LOG_LEVEL_ERROR) return 0, err } + + // Give default items to commander + if err := orm.GormDB.Create(&([]orm.CommanderItem{{ + // Wisdom Cube + CommanderID: accountId, + ItemID: 20001, + Count: 0, + }})).Error; err != nil { + logger.LogEvent("Client", "CreateCommander", fmt.Sprintf("failed to give default items to account %d: %v", accountId, err), logger.LOG_LEVEL_ERROR) + return 0, err + } + // Give default resources to commander + if err := orm.GormDB.Create(&([]orm.OwnedResource{{ + // Gold + CommanderID: accountId, + ResourceID: 1, + Amount: 0, + }, { + // Oil + CommanderID: accountId, + ResourceID: 2, + Amount: 0, + }, { + // Gem + CommanderID: accountId, + ResourceID: 4, + Amount: 0, + }})).Error; err != nil { + logger.LogEvent("Client", "CreateCommander", fmt.Sprintf("failed to give default resources to account %d: %v", accountId, err), logger.LOG_LEVEL_ERROR) + return 0, err + } + logger.LogEvent("Client", "CreateCommander", fmt.Sprintf("created new commander for account %d", accountId), logger.LOG_LEVEL_INFO) return accountId, nil } diff --git a/consts/update_data.go b/consts/update_data.go index bb884b6..7ae1e5c 100644 --- a/consts/update_data.go +++ b/consts/update_data.go @@ -8,13 +8,18 @@ package consts var ( RegionGateways = map[string]string{ "EN": "blhxusgate.yo-star.com", + "CN": "line1-login-bili-blhx.bilibiligame.net", } RegionProxies = map[string]string{ "EN": "blhxusproxy.yo-star.com", + // Its port in the apk should be 8080, but we don't need to care about it at the moment + "CN": "line1-bak-login-bili-blhx.bilibiligame.net", } // This might not change between regions, but it's here just in case Monday_0OclockTimestamps = map[string]uint32{ "EN": 1606114800, + // No one knows why, but according to version rules, this date may indeed be earlier than EN + "CN": 1606060800, } // This map represents the game's url on the respective platforms @@ -23,5 +28,11 @@ var ( "0": "https://play.google.com/store/apps/details?id=com.YoStarEN.AzurLane", "1": "https://itunes.apple.com/us/app/azur-lane/id1411126549", }, + "CN": { + // On Android, it should point to the latest apk address, + // but we can currently point directly to the official website + "0": "https://blhx.biligame.com/", + "1": "https://blhx.biligame.com/", + }, } ) diff --git a/main.go b/main.go index cbb5701..8a30c9c 100644 --- a/main.go +++ b/main.go @@ -77,10 +77,15 @@ func init() { } packets.RegisterPacketHandler(10800, []packets.PacketHandler{answer.Forge_SC10801}) packets.RegisterPacketHandler(8239, []packets.PacketHandler{answer.Forge_SC8239}) - packets.RegisterLocalizedPacketHandler(10020, packets.LocalizedHandler{ - EN: &[]packets.PacketHandler{answer.Forge_SC10021}, + packets.RegisterPacketHandler(10020, []packets.PacketHandler{answer.Forge_SC10021}) + packets.RegisterLocalizedPacketHandler(10802, packets.LocalizedHandler{ + CN: &[]packets.PacketHandler{answer.Forge_SC10803_CN_JP_KR_TW}, + TW: &[]packets.PacketHandler{answer.Forge_SC10803_CN_JP_KR_TW}, + JP: &[]packets.PacketHandler{answer.Forge_SC10803_CN_JP_KR_TW}, + KR: &[]packets.PacketHandler{answer.Forge_SC10803_CN_JP_KR_TW}, }) packets.RegisterPacketHandler(10022, []packets.PacketHandler{answer.JoinServer}) + packets.RegisterPacketHandler(10026, []packets.PacketHandler{answer.PlayerExist}) packets.RegisterPacketHandler(11001, []packets.PacketHandler{ answer.LastLogin, // SC_11000 answer.PlayerInfo, // SC_11003 @@ -143,6 +148,7 @@ func init() { packets.RegisterPacketHandler(10100, []packets.PacketHandler{answer.SendHeartbeat}) packets.RegisterPacketHandler(11013, []packets.PacketHandler{answer.GiveResources}) packets.RegisterPacketHandler(33000, []packets.PacketHandler{answer.UNK_33001}) + packets.RegisterPacketHandler(10994, []packets.PacketHandler{answer.CheaterMark}) // Build packets.RegisterPacketHandler(12002, []packets.PacketHandler{answer.ShipBuild}) @@ -163,6 +169,7 @@ func init() { // Shop packets.RegisterPacketHandler(16001, []packets.PacketHandler{answer.ShoppingCommandAnswer}) + packets.RegisterPacketHandler(11501, []packets.PacketHandler{answer.ChargeCommandAnswer}) // Retire packets.RegisterPacketHandler(12004, []packets.PacketHandler{answer.RetireShip}) @@ -225,4 +232,19 @@ func init() { // Ship comments tab packets.RegisterPacketHandler(17101, []packets.PacketHandler{answer.GetShipDiscuss}) // Ship discussion (placeholder) packets.RegisterPacketHandler(17107, []packets.PacketHandler{answer.UpdateShipLike}) + + // ??? + packets.RegisterPacketHandler(15300, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) { + return 0, 0, nil + }}) + + // ??? + packets.RegisterPacketHandler(12299, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) { + return 0, 0, nil + }}) + + // track + packets.RegisterPacketHandler(10993, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) { + return 0, 0, nil + }}) } diff --git a/misc/game_update.go b/misc/game_update.go index ec09727..ee2ef73 100644 --- a/misc/game_update.go +++ b/misc/game_update.go @@ -105,6 +105,10 @@ func GetGameHashes() HashMap { State: proto.Uint32(59), // 59 is something, might need to update this later? Platform: proto.String("1"), // iOS } + if os.Getenv("AL_REGION") == "CN" { + // fix version invalid? + promptUpdate.State = proto.Uint32(56) + } packet, err := proto.Marshal(&promptUpdate) if err != nil { logger.LogEvent("GameUpdate", "GetHashes", err.Error(), logger.LOG_LEVEL_ERROR)