add Player model
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "01eb28d6d5d4bfc205f7c8b2f8a3dc3a3d278b26c75f239cbd1cf26e4482e33d",
|
"originHash" : "48b60a6f8caccb2179aca6ee731ee84b313e8f73da96743e41514dc5bf29a68e",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "async-http-client",
|
"identity" : "async-http-client",
|
||||||
@@ -217,6 +217,15 @@
|
|||||||
"version" : "2.7.0"
|
"version" : "2.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swift-msgpack",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/nnabeyang/swift-msgpack.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "1c8dbd506c68888df3fd5df4ff56cef9cb39c388",
|
||||||
|
"version" : "0.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-nio",
|
"identity" : "swift-nio",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
@@ -17,6 +17,8 @@ let package = Package(
|
|||||||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
|
.package(url: "https://github.com/apple/swift-nio.git", from: "2.65.0"),
|
||||||
// JWTs
|
// JWTs
|
||||||
.package(url: "https://github.com/vapor/jwt.git", from: "5.0.0"),
|
.package(url: "https://github.com/vapor/jwt.git", from: "5.0.0"),
|
||||||
|
// MsgPack
|
||||||
|
.package(url: "https://github.com/nnabeyang/swift-msgpack.git", from: "0.7.0")
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.executableTarget(
|
.executableTarget(
|
||||||
@@ -28,6 +30,7 @@ let package = Package(
|
|||||||
.product(name: "NIOCore", package: "swift-nio"),
|
.product(name: "NIOCore", package: "swift-nio"),
|
||||||
.product(name: "NIOPosix", package: "swift-nio"),
|
.product(name: "NIOPosix", package: "swift-nio"),
|
||||||
.product(name: "JWT", package: "jwt"),
|
.product(name: "JWT", package: "jwt"),
|
||||||
|
.product(name: "SwiftMsgpack", package: "swift-msgpack"),
|
||||||
],
|
],
|
||||||
swiftSettings: swiftSettings
|
swiftSettings: swiftSettings
|
||||||
),
|
),
|
||||||
|
8
Sources/stella/Controllers/Api/ApiController.swift
Normal file
8
Sources/stella/Controllers/Api/ApiController.swift
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import Vapor
|
||||||
|
|
||||||
|
struct ApiController: RouteCollection {
|
||||||
|
func boot(routes: any RoutesBuilder) throws {
|
||||||
|
let group = routes.grouped("latest", "api", "index.php")
|
||||||
|
try group.register(collection: ToolController())
|
||||||
|
}
|
||||||
|
}
|
34
Sources/stella/Controllers/Api/ToolController.swift
Normal file
34
Sources/stella/Controllers/Api/ToolController.swift
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import Vapor
|
||||||
|
import SwiftMsgpack
|
||||||
|
import JWT
|
||||||
|
|
||||||
|
struct ToolController: RouteCollection {
|
||||||
|
func boot(routes: any RoutesBuilder) throws {
|
||||||
|
let group = routes.grouped("tool")
|
||||||
|
group.post("signup", use: self.signup)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
func signup(req: Request) async throws -> Response {
|
||||||
|
let body = try req.content.decode(SignupReq.self, using: MsgPackDecoder())
|
||||||
|
|
||||||
|
let session = try await req.jwt.verify(body.access_token, as: SessionPayload.self)
|
||||||
|
guard session.type == SessionType.ZAT.rawValue else {
|
||||||
|
throw Abort(.forbidden, reason: "Invalid access token")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
throw Abort(.notImplemented)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SignupReq: Content {
|
||||||
|
let app_secret: String
|
||||||
|
let access_token: String
|
||||||
|
let storage_directory_path: String
|
||||||
|
let app_admin: String
|
||||||
|
let kakao_pid: String
|
||||||
|
let device_id: Double
|
||||||
|
let idp_code: String
|
||||||
|
}
|
@@ -6,6 +6,7 @@ struct AuthController: RouteCollection {
|
|||||||
routes.post("v4", "device", "accessToken", "create", use: self.createAccessToken)
|
routes.post("v4", "device", "accessToken", "create", use: self.createAccessToken)
|
||||||
routes.post("v3", "agreement", "getForLogin", use: self.loginAgreement)
|
routes.post("v3", "agreement", "getForLogin", use: self.loginAgreement)
|
||||||
routes.post("v4", "auth", "loginDevice", use: self.loginDevice)
|
routes.post("v4", "auth", "loginDevice", use: self.loginDevice)
|
||||||
|
routes.post("v3", "zat", "login", use: self.zatLogin)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sendable
|
@Sendable
|
||||||
@@ -67,14 +68,19 @@ struct AuthController: RouteCollection {
|
|||||||
} else if let existingAccount = try await Account.query(on: req.db).filter(\.$idpId == idpId).first() {
|
} else if let existingAccount = try await Account.query(on: req.db).filter(\.$idpId == idpId).first() {
|
||||||
account = existingAccount
|
account = existingAccount
|
||||||
} else {
|
} else {
|
||||||
let account = Account(appId: body.appId, idpAlias: idpAlias, idpCode: "zd3", idpId: idpId, status: "normal")
|
account = Account(appId: body.appId, idpAlias: idpAlias, idpCode: "zd3", idpId: idpId, status: "normal")
|
||||||
try await account.create(on: req.db)
|
try await account!.create(on: req.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let account = account else {
|
guard let account = account else {
|
||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if account.idpAlias != idpAlias {
|
||||||
|
account.idpAlias = idpAlias
|
||||||
|
try await account.save(on: req.db)
|
||||||
|
}
|
||||||
|
|
||||||
let zatExpiry = Date.now.advanced(by: 43200)
|
let zatExpiry = Date.now.advanced(by: 43200)
|
||||||
let zrtExpiry = Date.now.advanced(by: 2592000)
|
let zrtExpiry = Date.now.advanced(by: 2592000)
|
||||||
|
|
||||||
@@ -91,13 +97,17 @@ struct AuthController: RouteCollection {
|
|||||||
externalToken: "",
|
externalToken: "",
|
||||||
zat: zatToken,
|
zat: zatToken,
|
||||||
zrt: zrtToken,
|
zrt: zrtToken,
|
||||||
player: Player(
|
player: LoginPlayer(
|
||||||
idpId: account.idpId,
|
idpId: account.idpId,
|
||||||
appId: account.appId,
|
appId: account.appId,
|
||||||
playerId: String(try account.requireID()),
|
playerId: String(try account.requireID()),
|
||||||
|
agreemenet: nil,
|
||||||
pushOption: PushOptionResponse(night: "n", player: "n"),
|
pushOption: PushOptionResponse(night: "n", player: "n"),
|
||||||
regTime: Int(account.regDate.timeIntervalSince1970),
|
regTime: Int(account.regDate.timeIntervalSince1970),
|
||||||
idpAlias: idpAlias,
|
idpAlias: idpAlias,
|
||||||
|
idpCode: nil,
|
||||||
|
lang: nil,
|
||||||
|
lastLoginTime: nil,
|
||||||
firstLoginTime: Int(account.firstLogin.timeIntervalSince1970),
|
firstLoginTime: Int(account.firstLogin.timeIntervalSince1970),
|
||||||
status: account.status
|
status: account.status
|
||||||
)
|
)
|
||||||
@@ -105,6 +115,110 @@ struct AuthController: RouteCollection {
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Sendable
|
||||||
|
func zatLogin(req: Request) async throws -> LoginDeviceRes {
|
||||||
|
let body = try req.content.decode(ZatLoginReq.self, as: .json)
|
||||||
|
if let session = try? await req.jwt.verify(body.zat, as: SessionPayload.self) {
|
||||||
|
guard session.type == SessionType.ZAT.rawValue && session.accountId.value == body.playerId else {
|
||||||
|
throw Abort(.badRequest, reason: "Invalid zat provided.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard
|
||||||
|
let accountId = Int(body.playerId),
|
||||||
|
let account = try await Account.query(on: req.db)
|
||||||
|
.filter(\.$id == accountId)
|
||||||
|
.first()
|
||||||
|
else {
|
||||||
|
throw Abort(.badRequest, reason: "Invalid playerId")
|
||||||
|
}
|
||||||
|
|
||||||
|
account.lastLogin = Date.now
|
||||||
|
try await account.save(on: req.db)
|
||||||
|
|
||||||
|
let zatExpiry = Date.now.advanced(by: 43200)
|
||||||
|
|
||||||
|
let session = generateToken(accountId: try account.requireID(), expires: zatExpiry, type: SessionType.ZAT)
|
||||||
|
let zatToken = try await req.jwt.sign(session)
|
||||||
|
return LoginDeviceRes(
|
||||||
|
zatExpiryTime: Int(zatExpiry.timeIntervalSince1970) * 1000,
|
||||||
|
zrtExpiryTime: nil,
|
||||||
|
firstLogin: false,
|
||||||
|
externalToken: "",
|
||||||
|
zat: zatToken,
|
||||||
|
zrt: nil,
|
||||||
|
player: LoginPlayer(
|
||||||
|
idpId: account.idpId,
|
||||||
|
appId: account.appId,
|
||||||
|
playerId: String(accountId),
|
||||||
|
agreemenet: AgreementResponse(E001: "y", E002: "y", E006: "y", N002: "n", N003: "n", timestamp: "1717623430484"),
|
||||||
|
pushOption: PushOptionResponse(night: "n", player: "n"),
|
||||||
|
regTime: Int(account.regDate.timeIntervalSince1970) * 1000,
|
||||||
|
idpAlias: account.idpAlias,
|
||||||
|
idpCode: account.idpCode,
|
||||||
|
lang: body.lang,
|
||||||
|
lastLoginTime: Int(account.lastLogin.timeIntervalSince1970) * 1000,
|
||||||
|
firstLoginTime: Int(account.firstLogin.timeIntervalSince1970) * 1000,
|
||||||
|
status: account.status
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ZatLoginReq: Content {
|
||||||
|
let adid: String
|
||||||
|
let appId: String
|
||||||
|
let appSecret: String
|
||||||
|
let appVer: String
|
||||||
|
let clientTime: Int
|
||||||
|
let country: String
|
||||||
|
let deviceId: String
|
||||||
|
let deviceModel: String
|
||||||
|
let fields: [String]
|
||||||
|
let gsiToken: Bool?
|
||||||
|
let lang: String
|
||||||
|
let loginType: String
|
||||||
|
let market: String
|
||||||
|
let network: String
|
||||||
|
let os: String
|
||||||
|
let playerId: String
|
||||||
|
let resume: Bool
|
||||||
|
let retryNo: Int?
|
||||||
|
let sdkVer: String
|
||||||
|
let telecom: String
|
||||||
|
let timezoneOffset: Int
|
||||||
|
let usimCountry: String?
|
||||||
|
let whiteKey: String
|
||||||
|
let zat: String
|
||||||
|
|
||||||
|
init(from decoder: any Decoder) throws {
|
||||||
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
|
adid = try container.decode(String.self, forKey: .adid)
|
||||||
|
appId = try container.decode(String.self, forKey: .appId)
|
||||||
|
appSecret = try container.decode(String.self, forKey: .appSecret)
|
||||||
|
appVer = try container.decode(String.self, forKey: .appVer)
|
||||||
|
clientTime = try container.decode(Int.self, forKey: .clientTime)
|
||||||
|
country = try container.decode(String.self, forKey: .country)
|
||||||
|
deviceId = try container.decode(String.self, forKey: .deviceId)
|
||||||
|
deviceModel = try container.decode(String.self, forKey: .deviceModel)
|
||||||
|
fields = try container.decode([String].self, forKey: .fields)
|
||||||
|
gsiToken = try container.decodeIfPresent(Bool.self, forKey: .gsiToken)
|
||||||
|
lang = try container.decode(String.self, forKey: .lang)
|
||||||
|
loginType = try container.decode(String.self, forKey: .loginType)
|
||||||
|
market = try container.decode(String.self, forKey: .market)
|
||||||
|
network = try container.decode(String.self, forKey: .network)
|
||||||
|
os = try container.decode(String.self, forKey: .os)
|
||||||
|
playerId = try container.decode(String.self, forKey: .playerId)
|
||||||
|
resume = try container.decode(Bool.self, forKey: .resume)
|
||||||
|
retryNo = try container.decodeIfPresent(Int.self, forKey: .retryNo)
|
||||||
|
sdkVer = try container.decode(String.self, forKey: .sdkVer)
|
||||||
|
telecom = try container.decode(String.self, forKey: .telecom)
|
||||||
|
timezoneOffset = try container.decode(Int.self, forKey: .timezoneOffset)
|
||||||
|
usimCountry = try container.decodeIfPresent(String.self, forKey: .usimCountry)
|
||||||
|
whiteKey = try container.decode(String.self, forKey: .whiteKey)
|
||||||
|
zat = try container.decode(String.self, forKey: .zat)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AccessTokenRes: Content {
|
struct AccessTokenRes: Content {
|
||||||
@@ -152,21 +266,25 @@ struct LoginDeviceReq: Content {
|
|||||||
|
|
||||||
struct LoginDeviceRes: Content {
|
struct LoginDeviceRes: Content {
|
||||||
let zatExpiryTime: Int
|
let zatExpiryTime: Int
|
||||||
let zrtExpiryTime: Int
|
let zrtExpiryTime: Int?
|
||||||
let firstLogin: Bool
|
let firstLogin: Bool
|
||||||
let externalToken: String
|
let externalToken: String
|
||||||
let zat: String
|
let zat: String
|
||||||
let zrt: String
|
let zrt: String?
|
||||||
let player: Player
|
let player: LoginPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Player: Content {
|
struct LoginPlayer: Content {
|
||||||
let idpId: String
|
let idpId: String
|
||||||
let appId: String
|
let appId: String
|
||||||
let playerId: String
|
let playerId: String
|
||||||
|
let agreemenet: AgreementResponse?
|
||||||
let pushOption: PushOptionResponse
|
let pushOption: PushOptionResponse
|
||||||
let regTime: Int
|
let regTime: Int
|
||||||
let idpAlias: String
|
let idpAlias: String
|
||||||
|
let idpCode: String?
|
||||||
|
let lang: String?
|
||||||
|
let lastLoginTime: Int?
|
||||||
let firstLoginTime: Int
|
let firstLoginTime: Int
|
||||||
let status: String
|
let status: String
|
||||||
}
|
}
|
||||||
|
18
Sources/stella/Decoders/MsgPack.swift
Normal file
18
Sources/stella/Decoders/MsgPack.swift
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import SwiftMsgpack
|
||||||
|
import Vapor
|
||||||
|
|
||||||
|
extension MsgPackEncoder: @retroactive ContentEncoder, @retroactive @unchecked Sendable {
|
||||||
|
public func encode<E>(_ encodable: E, to body: inout ByteBuffer, headers: inout HTTPHeaders) throws where E : Encodable {
|
||||||
|
let data = try self.encode(encodable)
|
||||||
|
body.writeString(data.base64EncodedString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension MsgPackDecoder: @retroactive ContentDecoder, @retroactive @unchecked Sendable {
|
||||||
|
public func decode<D>(_ decodable: D.Type, from body: ByteBuffer, headers: HTTPHeaders) throws -> D where D : Decodable {
|
||||||
|
guard let base64String = body.peekString(length: body.capacity), let data = Data(base64Encoded: base64String) else {
|
||||||
|
throw Abort(.badRequest)
|
||||||
|
}
|
||||||
|
return try self.decode(decodable, from: data)
|
||||||
|
}
|
||||||
|
}
|
39
Sources/stella/Migrations/CreatePlayers.swift
Normal file
39
Sources/stella/Migrations/CreatePlayers.swift
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import Fluent
|
||||||
|
|
||||||
|
struct CreatePlayers: AsyncMigration {
|
||||||
|
func prepare(on database: any Database) async throws {
|
||||||
|
try await database.schema("players")
|
||||||
|
.field("id", .int, .identifier(auto: true))
|
||||||
|
.field("stamina", .int, .required)
|
||||||
|
.field("stamina_heal_time", .date, .required)
|
||||||
|
.field("boost_point", .int, .required)
|
||||||
|
.field("boss_boost_point", .int, .required)
|
||||||
|
.field("transition_state", .int, .required)
|
||||||
|
.field("role", .int, .required)
|
||||||
|
.field("name", .string, .required)
|
||||||
|
.field("last_login_time", .date, .required)
|
||||||
|
.field("comment", .string, .required)
|
||||||
|
.field("vmoney", .int, .required)
|
||||||
|
.field("free_vmoney", .int, .required)
|
||||||
|
.field("rank_point", .int, .required)
|
||||||
|
.field("star_crumb", .int, .required)
|
||||||
|
.field("bond_token", .int, .required)
|
||||||
|
.field("exp_pool", .int, .required)
|
||||||
|
.field("exp_pooled_time", .date, .required)
|
||||||
|
.field("leader_character_id", .int, .required)
|
||||||
|
.field("party_slot", .int, .required)
|
||||||
|
.field("degree_id", .int, .required)
|
||||||
|
.field("birth", .int, .required)
|
||||||
|
.field("free_mana", .int, .required)
|
||||||
|
.field("paid_mana", .int, .required)
|
||||||
|
.field("enable_auto_3x", .bool, .required)
|
||||||
|
.field("account_id", .int, .required)
|
||||||
|
.field("tutorial_step", .int, .required)
|
||||||
|
.field("tutorial_skip_flag", .int, .required)
|
||||||
|
.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
func revert(on database: any Database) async throws {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -1,8 +1,5 @@
|
|||||||
import Fluent
|
import Fluent
|
||||||
|
|
||||||
/// Property wrappers interact poorly with `Sendable` checking, causing a warning for the `@ID` property
|
|
||||||
/// It is recommended you write your model with sendability checking on and then suppress the warning
|
|
||||||
/// afterwards with `@unchecked Sendable`.
|
|
||||||
final class Account: Model, @unchecked Sendable {
|
final class Account: Model, @unchecked Sendable {
|
||||||
static let schema = "accounts"
|
static let schema = "accounts"
|
||||||
|
|
||||||
|
151
Sources/stella/Models/Player.swift
Normal file
151
Sources/stella/Models/Player.swift
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import Fluent
|
||||||
|
|
||||||
|
final class Player: Model, @unchecked Sendable {
|
||||||
|
static let schema = "players"
|
||||||
|
|
||||||
|
@ID(custom: "id", generatedBy: .database)
|
||||||
|
var id: Int?
|
||||||
|
|
||||||
|
@Field(key: "stamina")
|
||||||
|
var stamina: Int
|
||||||
|
@Field(key: "stamina_heal_time")
|
||||||
|
var staminaHealTime: Date
|
||||||
|
@Field(key: "boost_point")
|
||||||
|
var boostPoint: Int
|
||||||
|
@Field(key: "boss_boost_point")
|
||||||
|
var bossBoostPoint: Int
|
||||||
|
@Field(key: "transition_state")
|
||||||
|
var transitionState: Int
|
||||||
|
@Field(key: "role")
|
||||||
|
var role: Int
|
||||||
|
@Field(key: "name")
|
||||||
|
var name: String
|
||||||
|
@Field(key: "last_login_time")
|
||||||
|
var lastLoginTime: Date
|
||||||
|
@Field(key: "comment")
|
||||||
|
var comment: String
|
||||||
|
@Field(key: "vmoney")
|
||||||
|
var vmoney: Int
|
||||||
|
@Field(key: "free_vmoney")
|
||||||
|
var freeVmoney: Int
|
||||||
|
@Field(key: "rank_point")
|
||||||
|
var rankPoint: Int
|
||||||
|
@Field(key: "star_crumb")
|
||||||
|
var starCrumb: Int
|
||||||
|
@Field(key: "bond_token")
|
||||||
|
var bondToken: Int
|
||||||
|
@Field(key: "exp_pool")
|
||||||
|
var expPool: Int
|
||||||
|
@Field(key: "exp_pooled_time")
|
||||||
|
var expPooledTime: Date
|
||||||
|
@Field(key: "leader_character_id")
|
||||||
|
var leaderCharacterId: Int
|
||||||
|
@Field(key: "party_slot")
|
||||||
|
var partySlot: Int
|
||||||
|
@Field(key: "degree_id")
|
||||||
|
var degreeId: Int
|
||||||
|
@Field(key: "birth")
|
||||||
|
var birth: Int
|
||||||
|
@Field(key: "free_mana")
|
||||||
|
var freeMana: Int
|
||||||
|
@Field(key: "paid_mana")
|
||||||
|
var paidMana: Int
|
||||||
|
@Field(key: "enable_auto_3x")
|
||||||
|
var enableAuto3x: Bool
|
||||||
|
@Parent(key: "account_id")
|
||||||
|
var account: Account
|
||||||
|
@Field(key: "tutorial_step")
|
||||||
|
var tutorialStep: Int?
|
||||||
|
@Field(key: "tutorial_skip_flag")
|
||||||
|
var tutorialSkipFlag: Int?
|
||||||
|
|
||||||
|
init() { }
|
||||||
|
|
||||||
|
init(
|
||||||
|
stamina: Int,
|
||||||
|
staminaHealTime: Date,
|
||||||
|
boostPoint: Int,
|
||||||
|
bossBoostPoint: Int,
|
||||||
|
transitionState: Int,
|
||||||
|
role: Int,
|
||||||
|
name: String,
|
||||||
|
lastLoginTime: Date,
|
||||||
|
comment: String,
|
||||||
|
vmoney: Int,
|
||||||
|
freeVmoney: Int,
|
||||||
|
rankPoint: Int,
|
||||||
|
starCrumb: Int,
|
||||||
|
bondToken: Int,
|
||||||
|
expPool: Int,
|
||||||
|
expPooledTime: Date,
|
||||||
|
leaderCharacterId: Int,
|
||||||
|
partySlot: Int,
|
||||||
|
degreeId: Int,
|
||||||
|
birth: Int,
|
||||||
|
freeMana: Int,
|
||||||
|
paidMana: Int,
|
||||||
|
enableAuto3x: Bool,
|
||||||
|
account: Account,
|
||||||
|
tutorialStep: Int?,
|
||||||
|
tutorialSkipFlag: Int?
|
||||||
|
) {
|
||||||
|
self.stamina = stamina
|
||||||
|
self.staminaHealTime = staminaHealTime
|
||||||
|
self.boostPoint = boostPoint
|
||||||
|
self.bossBoostPoint = bossBoostPoint
|
||||||
|
self.transitionState = transitionState
|
||||||
|
self.role = role
|
||||||
|
self.name = name
|
||||||
|
self.lastLoginTime = lastLoginTime
|
||||||
|
self.comment = comment
|
||||||
|
self.vmoney = vmoney
|
||||||
|
self.freeVmoney = freeVmoney
|
||||||
|
self.rankPoint = rankPoint
|
||||||
|
self.starCrumb = starCrumb
|
||||||
|
self.bondToken = bondToken
|
||||||
|
self.expPool = expPool
|
||||||
|
self.expPooledTime = expPooledTime
|
||||||
|
self.leaderCharacterId = leaderCharacterId
|
||||||
|
self.partySlot = partySlot
|
||||||
|
self.degreeId = degreeId
|
||||||
|
self.birth = birth
|
||||||
|
self.freeMana = freeMana
|
||||||
|
self.paidMana = paidMana
|
||||||
|
self.enableAuto3x = enableAuto3x
|
||||||
|
self.tutorialStep = tutorialStep
|
||||||
|
self.tutorialSkipFlag = tutorialSkipFlag
|
||||||
|
}
|
||||||
|
|
||||||
|
static func createDefault(account: Account) -> Player {
|
||||||
|
return Player(
|
||||||
|
stamina: 20,
|
||||||
|
staminaHealTime: Date.now,
|
||||||
|
boostPoint: 3,
|
||||||
|
bossBoostPoint: 3,
|
||||||
|
transitionState: 0,
|
||||||
|
role: 1,
|
||||||
|
name: "플레이어",
|
||||||
|
lastLoginTime: Date.now,
|
||||||
|
comment: "Nice to meet you.",
|
||||||
|
vmoney: 0,
|
||||||
|
freeVmoney: 150,
|
||||||
|
rankPoint: 10,
|
||||||
|
starCrumb: 0,
|
||||||
|
bondToken: 0,
|
||||||
|
expPool: 0,
|
||||||
|
expPooledTime: Date.now,
|
||||||
|
leaderCharacterId: 1,
|
||||||
|
partySlot: 1,
|
||||||
|
degreeId: 1,
|
||||||
|
birth: 19900101,
|
||||||
|
freeMana: 1000,
|
||||||
|
paidMana: 0,
|
||||||
|
enableAuto3x: false,
|
||||||
|
account: account,
|
||||||
|
tutorialStep: 0,
|
||||||
|
tutorialSkipFlag: nil
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -12,4 +12,5 @@ func routes(_ app: Application) throws {
|
|||||||
|
|
||||||
try app.register(collection: InfodeskController())
|
try app.register(collection: InfodeskController())
|
||||||
try app.register(collection: OpenApiController())
|
try app.register(collection: OpenApiController())
|
||||||
|
try app.register(collection: ApiController())
|
||||||
}
|
}
|
||||||
|
1
start-mitm.sh
Executable file
1
start-mitm.sh
Executable file
@@ -0,0 +1 @@
|
|||||||
|
mitmweb --set connection_strategy=lazy --allow-hosts gc-openapi-zinny3.kakaogames.com --allow-hosts gc-infodesk-zinny3.kakaogames.com --allow-hosts na.wdfp.kakaogames.com --allow-hosts patch.wdfp.kakaogames.com -s ./mitm-redirect-traffic.py
|
Reference in New Issue
Block a user