This repository was archived by the owner on Nov 19, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathmain.go
277 lines (249 loc) · 11.7 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
package main
import (
"fmt"
"log"
"os"
"os/signal"
"github.com/akamensky/argparse"
"github.com/ggmolly/belfast/answer"
"github.com/ggmolly/belfast/connection"
"github.com/ggmolly/belfast/consts"
"github.com/ggmolly/belfast/debug"
"github.com/ggmolly/belfast/logger"
"github.com/ggmolly/belfast/misc"
"github.com/ggmolly/belfast/orm"
"github.com/ggmolly/belfast/packets"
"github.com/ggmolly/belfast/protobuf"
"github.com/ggmolly/belfast/web"
"github.com/joho/godotenv"
"github.com/mattn/go-tty"
"google.golang.org/protobuf/proto"
)
var validRegions = map[string]interface{}{
"CN": nil,
"EN": nil,
"JP": nil,
"KR": nil,
"TW": nil,
}
func main() {
parser := argparse.NewParser("belfast", "Azur Lane server emulator")
reseed := parser.Flag("s", "reseed", &argparse.Options{
Required: false,
Help: "Forces the reseed of the database with the latest data",
Default: false,
})
adb := parser.Flag("a", "adb", &argparse.Options{
Required: false,
Help: "Parse ADB logs for debugging purposes (experimental -- tested on Linux only)",
Default: false,
})
flushLogcat := parser.Flag("f", "flush-logcat", &argparse.Options{
Required: false,
Help: "Flush the logcat buffer upon starting the ADB watcher",
Default: false,
})
if err := parser.Parse(os.Args); err != nil {
fmt.Print(parser.Usage(err))
os.Exit(1)
}
if *reseed {
logger.LogEvent("Reseed", "Forced", "Forcing reseed of the database...", logger.LOG_LEVEL_INFO)
misc.UpdateAllData(os.Getenv("AL_REGION"))
}
server := connection.NewServer("0.0.0.0", 80, packets.Dispatch)
// Open TTY for adb controls
tty, err := tty.Open()
if err != nil {
log.Println("failed to open tty:", err)
log.Println("adb background routine will be disabled.")
return
}
// wait for SIGINT
sigChannel := make(chan os.Signal, 1)
signal.Notify(sigChannel, os.Interrupt)
go func() {
<-sigChannel
fmt.Printf("\r") // trick to avoid ^C in the terminal, could use low-level RawMode() but why bother
// disconnect all clients from the server
server.DisconnectAll(consts.DR_CONNECTION_TO_SERVER_LOST)
os.Exit(0)
}()
// Prepare web server
go func() {
web.StartWeb()
}()
// Prepare adb background task
if *adb {
go debug.ADBRoutine(tty, *flushLogcat)
}
if err := server.Run(); err != nil {
logger.LogEvent("Server", "Run", fmt.Sprintf("%v", err), logger.LOG_LEVEL_ERROR)
tty.Close()
os.Exit(1)
}
}
func init() {
// Set log format to have the file name and line number
log.SetFlags(log.Lshortfile | log.LstdFlags)
err := godotenv.Load()
if err != nil {
logger.LogEvent("Environment", "Load", err.Error(), logger.LOG_LEVEL_ERROR)
}
// Check if the region is valid
if _, ok := validRegions[os.Getenv("AL_REGION")]; !ok {
logger.LogEvent("Environment", "Invalid", fmt.Sprintf("AL_REGION is not a valid region ('%s' was supplied)", os.Getenv("AL_REGION")), logger.LOG_LEVEL_ERROR)
os.Exit(1)
}
if orm.InitDatabase() { // if first run, populate the database
misc.UpdateAllData(os.Getenv("AL_REGION"))
}
packets.RegisterPacketHandler(10800, []packets.PacketHandler{answer.Forge_SC10801})
packets.RegisterPacketHandler(8239, []packets.PacketHandler{answer.Forge_SC8239})
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(10018, []packets.PacketHandler{answer.Forge_SC10019})
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
answer.PlayerBuffs, // SC_11015
answer.GetMetaProgress, // SC_63315
answer.LastOnlineInfo, // SC_11752
answer.ResourcesInfo, // SC_22001
answer.EventData, // SC_26120
answer.Meowfficers, // SC_25001
answer.CommanderCollection, // SC_17001
answer.OngoingBuilds, // SC_12024
answer.PlayerDock, // SC_12001
answer.CommanderDock, // SC_12010
answer.CommanderFleet, // SC_12101
answer.CommanderOwnedSkins, // SC_12201
answer.UNK_63000, // SC_63000
answer.ShipyardData, // SC_63100
answer.TechnologyNationProxy, // SC_64000
answer.CommanderStoryProgress, // SC_13001
answer.UNK_13002, // SC_13002
answer.CommanderCommissionsFleet, // SC_13201
answer.ShopData, // SC_16200
answer.UNK_33114, // SC_33114
answer.EquipedSpecialWeapons, // SC_14001
answer.EquippedWeaponSkin, // SC_14101
answer.OwnedItems, // SC_15001
answer.CommanderMissions, // SC_20001
answer.WeeklyMissions, // SC_20101
answer.DormData, // SC_19001
answer.FleetEnergyRecoverTime, // SC_12031
answer.GameMailbox, // SC_30001
answer.CommanderFriendList, // SC_50000
// answer.JuustagramData, // SC_11700
answer.Activities, // SC_11200
answer.PermanentActivites, // SC_11210
answer.GameNotices, // SC_11300
answer.SendPlayerShipCount, // SC_11002 -> Will trigger a scene change in the client
})
packets.RegisterPacketHandler(25026, []packets.PacketHandler{answer.UNK_25027})
packets.RegisterPacketHandler(34501, []packets.PacketHandler{answer.UNK_34502})
packets.RegisterPacketHandler(63317, []packets.PacketHandler{answer.MetaCharacterTacticsInfoRequestCommandResponse})
packets.RegisterPacketHandler(34001, []packets.PacketHandler{answer.GetMetaShipsPointsResponse})
packets.RegisterPacketHandler(18001, []packets.PacketHandler{answer.ExerciseEnemies})
packets.RegisterPacketHandler(60037, []packets.PacketHandler{answer.CommanderGuildData})
packets.RegisterPacketHandler(62100, []packets.PacketHandler{answer.CommanderGuildTechnologies})
packets.RegisterPacketHandler(26101, []packets.PacketHandler{answer.UNK_26102})
packets.RegisterPacketHandler(24020, []packets.PacketHandler{answer.UNK_24021})
packets.RegisterPacketHandler(11603, []packets.PacketHandler{answer.FetchSecondaryPasswordCommandResponse})
packets.RegisterPacketHandler(17203, []packets.PacketHandler{answer.UNK_17204})
packets.RegisterPacketHandler(16104, []packets.PacketHandler{answer.UNK_16105})
packets.RegisterPacketHandler(60100, []packets.PacketHandler{answer.CommanderGuildChat})
packets.RegisterPacketHandler(60102, []packets.PacketHandler{answer.GuildGetUserInfoCommand})
packets.RegisterPacketHandler(61009, []packets.PacketHandler{answer.GetMyAssaultFleetCommandResponse})
packets.RegisterPacketHandler(61011, []packets.PacketHandler{answer.GuildGetAssaultFleetCommandResponse})
packets.RegisterPacketHandler(61005, []packets.PacketHandler{answer.GuildGetActivationEventCommandResponse})
packets.RegisterPacketHandler(60003, []packets.PacketHandler{answer.GetGuildRequestsCommandResponse})
packets.RegisterPacketHandler(13505, []packets.PacketHandler{answer.UNK_13506})
packets.RegisterPacketHandler(11202, []packets.PacketHandler{answer.GiveItem})
packets.RegisterPacketHandler(11751, []packets.PacketHandler{answer.LastOnlineInfo})
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})
packets.RegisterPacketHandler(12008, []packets.PacketHandler{answer.BuildQuickFinish})
packets.RegisterPacketHandler(12043, []packets.PacketHandler{answer.BuildFinish})
packets.RegisterPacketHandler(12025, []packets.PacketHandler{answer.UNK_12026})
packets.RegisterPacketHandler(12045, []packets.PacketHandler{answer.ConfirmShip})
// Exchange ships
packets.RegisterPacketHandler(12047, []packets.PacketHandler{answer.ExchangeShip})
// Mails
packets.RegisterPacketHandler(30002, []packets.PacketHandler{answer.SendMailList})
packets.RegisterPacketHandler(30004, []packets.PacketHandler{answer.GetCollectionMailList})
packets.RegisterPacketHandler(30006, []packets.PacketHandler{answer.HandleMailDealCmd})
packets.RegisterPacketHandler(30008, []packets.PacketHandler{answer.DeleteArchivedMail})
// packets.RegisterPacketHandler(30010, []packets.PacketHandler{answer.UpdateMailImpFlag})
// Shop
packets.RegisterPacketHandler(16001, []packets.PacketHandler{answer.ShoppingCommandAnswer})
packets.RegisterPacketHandler(11501, []packets.PacketHandler{answer.ChargeCommandAnswer})
// Retire
packets.RegisterPacketHandler(12004, []packets.PacketHandler{answer.RetireShip})
// Chat
packets.RegisterPacketHandler(11401, []packets.PacketHandler{answer.ChatRoomChange})
packets.RegisterPacketHandler(50102, []packets.PacketHandler{answer.ReceiveChatMessage})
// Propose
packets.RegisterPacketHandler(12032, []packets.PacketHandler{answer.ProposeShip})
// Ship interaction quest
packets.RegisterPacketHandler(20007, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) {
response := protobuf.SC_20008{
Result: proto.Uint32(1),
}
return c.SendMessage(20008, &response)
}})
// Update secretaries
packets.RegisterPacketHandler(11011, []packets.PacketHandler{answer.UpdateSecretaries})
// Set ship as favorite
packets.RegisterPacketHandler(12040, []packets.PacketHandler{answer.SetFavoriteShip})
// Lock ships
packets.RegisterPacketHandler(12022, []packets.PacketHandler{answer.ChangeShipLockState})
// Change selected skin
packets.RegisterPacketHandler(12202, []packets.PacketHandler{answer.ChangeSelectedSkin})
// Rename proposed ship
packets.RegisterPacketHandler(12034, []packets.PacketHandler{answer.RenameProposedShip})
// Education / Child (aka. TB as secretary)
packets.RegisterPacketHandler(27000, []packets.PacketHandler{answer.UNK_27001})
packets.RegisterPacketHandler(27010, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) {
response := protobuf.SC_27011{}
return c.SendMessage(27011, &response)
}})
// Fleet
packets.RegisterPacketHandler(12102, []packets.PacketHandler{answer.FleetCommit})
packets.RegisterPacketHandler(12104, []packets.PacketHandler{answer.FleetRename})
packets.RegisterPacketHandler(13107, []packets.PacketHandler{func(b *[]byte, c *connection.Client) (int, int, error) {
response := protobuf.SC_13108{
Result: proto.Uint32(0),
}
return c.SendMessage(13108, &response)
}})
// UpdateCommonFlagCommand, unknown what it does
packets.RegisterPacketHandler(11019, []packets.PacketHandler{answer.UpdateCommonFlagCommand})
// 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
}})
}