From 5453af9b35063e2d668521440bf1c27b64de615f Mon Sep 17 00:00:00 2001 From: Hexagon Date: Sat, 12 Aug 2023 12:40:33 -0300 Subject: [PATCH] clubset: basic workshop support --- database/migrations/V0001__base-schema.sql | 14 +++-- .../fking/pangya/game/net/ClientPacketType.kt | 8 ++- .../ClubSetUpgradePacketHandler.kt | 3 +- ...lubWorkshopAcceptTransformPacketHandler.kt | 11 ++++ ...ubWorkshopDeclineTransformPacketHandler.kt | 11 ++++ .../ClubWorkshopRankUpPacketHandler.kt | 27 ++++++++++ .../game/packet/outbound/ClubSetReplies.kt | 51 +++++++++++++++++-- .../game/persistence/InventoryRepository.kt | 8 +++ .../game/persistence/jooq/indexes/Indexes.kt | 2 + .../game/persistence/jooq/tables/Account.kt | 4 +- .../jooq/tables/PlayerInventoryItem.kt | 22 ++++++-- .../records/PlayerInventoryItemRecord.kt | 46 ++++++++++++++--- .../work/fking/pangya/game/player/Item.kt | 12 ++++- .../pangya/game/player/ItemClubWorkshop.kt | 29 +++++++++++ .../work/fking/pangya/game/player/ItemUcc.kt | 24 +++++++++ .../pangya/game/task/ChangeClubSetStatTask.kt | 18 +++++-- jooq.xml | 16 ++++++ 17 files changed, 275 insertions(+), 31 deletions(-) rename game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/{ => clubworkshop}/ClubSetUpgradePacketHandler.kt (90%) create mode 100644 game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopAcceptTransformPacketHandler.kt create mode 100644 game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopDeclineTransformPacketHandler.kt create mode 100644 game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopRankUpPacketHandler.kt create mode 100644 game-server/src/main/kotlin/work/fking/pangya/game/player/ItemClubWorkshop.kt create mode 100644 game-server/src/main/kotlin/work/fking/pangya/game/player/ItemUcc.kt diff --git a/database/migrations/V0001__base-schema.sql b/database/migrations/V0001__base-schema.sql index 67cbd6b..ede62f2 100644 --- a/database/migrations/V0001__base-schema.sql +++ b/database/migrations/V0001__base-schema.sql @@ -10,6 +10,8 @@ CREATE TABLE account ( ); CREATE INDEX idx__account_uuid ON account (uuid); +CREATE UNIQUE INDEX idx__account_username ON account (username); +CREATE UNIQUE INDEX idx__account_nickname ON account (nickname); CREATE TABLE achievement ( iff_id int NOT NULL PRIMARY KEY, @@ -52,12 +54,14 @@ CREATE TABLE player_caddie ( CREATE UNIQUE INDEX idx_player_caddie ON player_caddie (account_uid, iff_id); CREATE TABLE player_inventory_item ( - uid serial PRIMARY KEY, - account_uid int NOT NULL + uid serial PRIMARY KEY, + account_uid int NOT NULL CONSTRAINT fk_player_inventory_item__account REFERENCES account (uid) ON DELETE CASCADE, - iff_id int NOT NULL, - quantity int DEFAULT 0, - stats json + iff_id int NOT NULL, + quantity int DEFAULT 0, + stats json, + ucc json, + club_workshop json ); CREATE TABLE player_equipment ( diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/net/ClientPacketType.kt b/game-server/src/main/kotlin/work/fking/pangya/game/net/ClientPacketType.kt index 88cd1e3..cbe238d 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/net/ClientPacketType.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/net/ClientPacketType.kt @@ -1,7 +1,7 @@ package work.fking.pangya.game.net import work.fking.pangya.game.packet.handler.AchievementStatusRequestPacketHandler -import work.fking.pangya.game.packet.handler.ClubSetUpgradePacketHandler +import work.fking.pangya.game.packet.handler.clubworkshop.ClubSetUpgradePacketHandler import work.fking.pangya.game.packet.handler.EquipmentUpdatePacketHandler import work.fking.pangya.game.packet.handler.JoinLobbyPacketHandler import work.fking.pangya.game.packet.handler.LeaveLobbyPacketHandler @@ -15,6 +15,9 @@ import work.fking.pangya.game.packet.handler.RareShopOpenPacketHandler import work.fking.pangya.game.packet.handler.SelectChannelPacketHandler import work.fking.pangya.game.packet.handler.UpdateChatMacrosPacketHandler import work.fking.pangya.game.packet.handler.UserProfileRequestPacketHandler +import work.fking.pangya.game.packet.handler.clubworkshop.ClubWorkshopAcceptTransformPacketHandler +import work.fking.pangya.game.packet.handler.clubworkshop.ClubWorkshopDeclineTransformPacketHandler +import work.fking.pangya.game.packet.handler.clubworkshop.ClubWorkshopRankUpPacketHandler import work.fking.pangya.game.packet.handler.match.MatchFinalStatsPacketHandler import work.fking.pangya.game.packet.handler.match.MatchFinishPlayerPreviewPacketHandler import work.fking.pangya.game.packet.handler.match.MatchHoleStartPacketHandler @@ -82,6 +85,9 @@ enum class ClientPacketType( PLAYER_RING_PROC(0x15d), MATCH_PLAYER_TOURNEY_SHOT(0x12f, MatchTourneyShotPacketHandler()), PAPEL_SHOP_PLAY(0x14b, PapelShopPlayPacketHandler()), + CLUB_WORKSHOP_RANK_UP(0x167, ClubWorkshopRankUpPacketHandler()), + CLUB_WORKSHOP_DECLINE_TRANSFORM(0x168, ClubWorkshopDeclineTransformPacketHandler()), + CLUB_WORKSHOP_ACCEPT_TRANSFORM(0x169, ClubWorkshopAcceptTransformPacketHandler()), LOGIN_BONUS_INFO(0x16e, LoginBonusStatusPacketHandler()), LOGIN_BONUS_CLAIM(0x16f, LoginBonusClaimPacketHandler()); diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/ClubSetUpgradePacketHandler.kt b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubSetUpgradePacketHandler.kt similarity index 90% rename from game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/ClubSetUpgradePacketHandler.kt rename to game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubSetUpgradePacketHandler.kt index a15f54a..4f937f5 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/ClubSetUpgradePacketHandler.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubSetUpgradePacketHandler.kt @@ -1,9 +1,8 @@ -package work.fking.pangya.game.packet.handler +package work.fking.pangya.game.packet.handler.clubworkshop import io.netty.buffer.ByteBuf import work.fking.pangya.game.GameServer import work.fking.pangya.game.net.ClientPacketHandler -import work.fking.pangya.game.packet.outbound.ClubSetReplies import work.fking.pangya.game.player.Player import work.fking.pangya.game.player.statById import work.fking.pangya.game.task.ChangeClubSetStatTask diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopAcceptTransformPacketHandler.kt b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopAcceptTransformPacketHandler.kt new file mode 100644 index 0000000..01ccdab --- /dev/null +++ b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopAcceptTransformPacketHandler.kt @@ -0,0 +1,11 @@ +package work.fking.pangya.game.packet.handler.clubworkshop + +import io.netty.buffer.ByteBuf +import work.fking.pangya.game.GameServer +import work.fking.pangya.game.net.ClientPacketHandler +import work.fking.pangya.game.player.Player + +class ClubWorkshopAcceptTransformPacketHandler : ClientPacketHandler { + override fun handle(server: GameServer, player: Player, packet: ByteBuf) { + } +} \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopDeclineTransformPacketHandler.kt b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopDeclineTransformPacketHandler.kt new file mode 100644 index 0000000..358a30a --- /dev/null +++ b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopDeclineTransformPacketHandler.kt @@ -0,0 +1,11 @@ +package work.fking.pangya.game.packet.handler.clubworkshop + +import io.netty.buffer.ByteBuf +import work.fking.pangya.game.GameServer +import work.fking.pangya.game.net.ClientPacketHandler +import work.fking.pangya.game.player.Player + +class ClubWorkshopDeclineTransformPacketHandler : ClientPacketHandler { + override fun handle(server: GameServer, player: Player, packet: ByteBuf) { + } +} \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopRankUpPacketHandler.kt b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopRankUpPacketHandler.kt new file mode 100644 index 0000000..6f320d6 --- /dev/null +++ b/game-server/src/main/kotlin/work/fking/pangya/game/packet/handler/clubworkshop/ClubWorkshopRankUpPacketHandler.kt @@ -0,0 +1,27 @@ +package work.fking.pangya.game.packet.handler.clubworkshop + +import io.netty.buffer.ByteBuf +import work.fking.pangya.game.GameServer +import work.fking.pangya.game.model.IFF_TYPE_CLUBSET +import work.fking.pangya.game.model.iffTypeFromId +import work.fking.pangya.game.net.ClientPacketHandler +import work.fking.pangya.game.packet.outbound.ClubSetReplies +import work.fking.pangya.game.player.Player + +class ClubWorkshopRankUpPacketHandler : ClientPacketHandler { + override fun handle(server: GameServer, player: Player, packet: ByteBuf) { + val cardIffId = packet.readIntLE() + val cardQuantity = packet.readShortLE() + val clubSetUid = packet.readIntLE() + println("cardIffId=$cardIffId, cardQuantity=$cardQuantity, clubSetUid=$clubSetUid") + + val clubSet = player.inventory.findByUid(clubSetUid) ?: throw IllegalStateException("Player ${player.nickname} tried to rank up a clubset it does not own ($clubSetUid)") + + val clubSetStats = clubSet.clubWorkshop.stats + val statBefore = clubSetStats[0] + clubSetStats[0]++ + val statAfter = clubSetStats[0] + player.write(ClubSetReplies.syncClubSetItem(clubSet, statBefore, statAfter)) + player.writeAndFlush(ClubSetReplies.workshopRankUpAck(clubSetUid, 0)) + } +} \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/packet/outbound/ClubSetReplies.kt b/game-server/src/main/kotlin/work/fking/pangya/game/packet/outbound/ClubSetReplies.kt index c4844c7..bfe1953 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/packet/outbound/ClubSetReplies.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/packet/outbound/ClubSetReplies.kt @@ -1,17 +1,62 @@ package work.fking.pangya.game.packet.outbound +import work.fking.pangya.game.player.Item +import work.fking.pangya.game.player.write import work.fking.pangya.networking.protocol.OutboundPacket +import java.time.Instant object ClubSetReplies { - fun upgradeAck(type: Int, stat: Int, itemUid: Int, cost: Long): OutboundPacket { + fun upgradeAck(result: UpgradeResult, stat: Int, itemUid: Int, cost: Long = 0): OutboundPacket { return OutboundPacket { buffer -> buffer.writeShortLE(0xa5) - buffer.writeByte(type) + buffer.writeByte(result.code) buffer.writeByte(1) // 0 doesn't upgrade a clubset but 1 does? buffer.writeByte(stat) buffer.writeIntLE(itemUid) - buffer.writeLongLE(cost) // TODO: how to calculate the upgrade cost? + buffer.writeLongLE(cost) } } + + fun workshopRankUpTransform(): OutboundPacket { + return OutboundPacket { buffer -> buffer.writeShortLE(0x241) } + } + + fun workshopRankUpAck(clubSetUid: Int, leveledUpStat: Int): OutboundPacket { + return OutboundPacket { buffer -> + buffer.writeShortLE(0x240) + buffer.writeIntLE(0) // result 0 = ok, 1 = 'System error' + + buffer.writeIntLE(leveledUpStat) // which stat leveled up + buffer.writeIntLE(clubSetUid) + } + } + + fun syncClubSetItem(item: Item, statBefore: Int, statAfter: Int): OutboundPacket { + return OutboundPacket { buffer -> + buffer.writeShortLE(0x216) + + buffer.writeIntLE(Instant.now().epochSecond.toInt()) + buffer.writeIntLE(1) + + buffer.writeByte(0x2) // this packet can sync multiple things, 0x2 means it's an inventory item + buffer.writeIntLE(item.iffId) + buffer.writeIntLE(item.uid) + buffer.writeIntLE(0) + buffer.writeIntLE(statBefore) + buffer.writeIntLE(statAfter) + buffer.writeIntLE(item.quantity) + buffer.writeZero(25) + buffer.write(item.clubWorkshop) + } + } + + enum class UpgradeResult(val code: Int) { + UPGRADE_SUCCESS(1), + DOWNGRADE_SUCCESS(2), + INSUFFICIENT_PANG(3), + INSUFFICIENT_SLOTS(4), + CANNOT_DOWNGRADE_ANYMORE(5), + FAILED_TO_UPGRADE(6) + } } \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/InventoryRepository.kt b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/InventoryRepository.kt index ba1f7fa..21c483b 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/InventoryRepository.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/InventoryRepository.kt @@ -6,6 +6,8 @@ import work.fking.pangya.game.persistence.jooq.tables.records.PlayerInventoryIte import work.fking.pangya.game.persistence.jooq.tables.references.PLAYER_INVENTORY_ITEM import work.fking.pangya.game.player.Inventory import work.fking.pangya.game.player.Item +import work.fking.pangya.game.player.nullItemClubWorkshop +import work.fking.pangya.game.player.nullItemUcc import java.util.concurrent.atomic.AtomicInteger interface InventoryRepository { @@ -47,6 +49,8 @@ class JooqInventoryRepository : InventoryRepository { iffId = it.iffId, quantity = it.quantity ?: 0, stats = it.stats ?: IntArray(0), + ucc = it.ucc ?: nullItemUcc(), + clubWorkshop = it.clubWorkshop ?: nullItemClubWorkshop() ) } @@ -67,10 +71,14 @@ class JooqInventoryRepository : InventoryRepository { .set(PLAYER_INVENTORY_ITEM.IFF_ID, item.iffId) .set(PLAYER_INVENTORY_ITEM.QUANTITY, item.quantity) .set(PLAYER_INVENTORY_ITEM.STATS, item.stats) + .set(PLAYER_INVENTORY_ITEM.UCC, item.ucc) + .set(PLAYER_INVENTORY_ITEM.CLUB_WORKSHOP, item.clubWorkshop) .onConflict(PLAYER_INVENTORY_ITEM_PKEY.fields) .doUpdate() .set(PLAYER_INVENTORY_ITEM.QUANTITY, item.quantity) .set(PLAYER_INVENTORY_ITEM.STATS, item.stats) + .set(PLAYER_INVENTORY_ITEM.UCC, item.ucc) + .set(PLAYER_INVENTORY_ITEM.CLUB_WORKSHOP, item.clubWorkshop) .returningResult(PLAYER_INVENTORY_ITEM.UID) .fetchOneInto(Int::class.java) diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/indexes/Indexes.kt b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/indexes/Indexes.kt index 223d6ac..1069c46 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/indexes/Indexes.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/indexes/Indexes.kt @@ -22,6 +22,8 @@ import work.fking.pangya.game.persistence.jooq.tables.PlayerCharacter // ------------------------------------------------------------------------- val FLYWAY_SCHEMA_HISTORY_S_IDX: Index = Internal.createIndex(DSL.name("flyway_schema_history_s_idx"), FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY, arrayOf(FlywaySchemaHistory.FLYWAY_SCHEMA_HISTORY.SUCCESS), false) +val IDX__ACCOUNT_NICKNAME: Index = Internal.createIndex(DSL.name("idx__account_nickname"), Account.ACCOUNT, arrayOf(Account.ACCOUNT.NICKNAME), true) +val IDX__ACCOUNT_USERNAME: Index = Internal.createIndex(DSL.name("idx__account_username"), Account.ACCOUNT, arrayOf(Account.ACCOUNT.USERNAME), true) val IDX__ACCOUNT_UUID: Index = Internal.createIndex(DSL.name("idx__account_uuid"), Account.ACCOUNT, arrayOf(Account.ACCOUNT.UUID), false) val IDX_PLAYER_ACHIEVEMENT: Index = Internal.createIndex(DSL.name("idx_player_achievement"), PlayerAchievement.PLAYER_ACHIEVEMENT, arrayOf(PlayerAchievement.PLAYER_ACHIEVEMENT.ACCOUNT_UID, PlayerAchievement.PLAYER_ACHIEVEMENT.IFF_ID), true) val IDX_PLAYER_ACHIEVEMENT_MILESTONE: Index = Internal.createIndex(DSL.name("idx_player_achievement_milestone"), PlayerAchievementMilestone.PLAYER_ACHIEVEMENT_MILESTONE, arrayOf(PlayerAchievementMilestone.PLAYER_ACHIEVEMENT_MILESTONE.PLAYER_ACHIEVEMENT_UID, PlayerAchievementMilestone.PLAYER_ACHIEVEMENT_MILESTONE.IFF_ID), true) diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/Account.kt b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/Account.kt index 2b97ed3..3cc9951 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/Account.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/Account.kt @@ -29,6 +29,8 @@ import org.jooq.impl.SQLDataType import org.jooq.impl.TableImpl import work.fking.pangya.game.persistence.jooq.Public +import work.fking.pangya.game.persistence.jooq.indexes.IDX__ACCOUNT_NICKNAME +import work.fking.pangya.game.persistence.jooq.indexes.IDX__ACCOUNT_USERNAME import work.fking.pangya.game.persistence.jooq.indexes.IDX__ACCOUNT_UUID import work.fking.pangya.game.persistence.jooq.keys.ACCOUNT_PKEY import work.fking.pangya.game.persistence.jooq.tables.records.AccountRecord @@ -127,7 +129,7 @@ open class Account( constructor(child: Table, key: ForeignKey): this(Internal.createPathAlias(child, key), child, key, ACCOUNT, null) override fun getSchema(): Schema? = if (aliased()) null else Public.PUBLIC - override fun getIndexes(): List = listOf(IDX__ACCOUNT_UUID) + override fun getIndexes(): List = listOf(IDX__ACCOUNT_NICKNAME, IDX__ACCOUNT_USERNAME, IDX__ACCOUNT_UUID) override fun getIdentity(): Identity = super.getIdentity() as Identity override fun getPrimaryKey(): UniqueKey = ACCOUNT_PKEY override fun `as`(alias: String): Account = Account(DSL.name(alias), this) diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/PlayerInventoryItem.kt b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/PlayerInventoryItem.kt index 2f13041..7977718 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/PlayerInventoryItem.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/PlayerInventoryItem.kt @@ -14,7 +14,7 @@ import org.jooq.Identity import org.jooq.Name import org.jooq.Record import org.jooq.Records -import org.jooq.Row5 +import org.jooq.Row7 import org.jooq.Schema import org.jooq.SelectField import org.jooq.Table @@ -31,6 +31,8 @@ import work.fking.pangya.game.persistence.jooq.Public import work.fking.pangya.game.persistence.jooq.keys.PLAYER_INVENTORY_ITEM_PKEY import work.fking.pangya.game.persistence.jooq.keys.PLAYER_INVENTORY_ITEM__FK_PLAYER_INVENTORY_ITEM__ACCOUNT import work.fking.pangya.game.persistence.jooq.tables.records.PlayerInventoryItemRecord +import work.fking.pangya.game.player.ItemClubWorkshop +import work.fking.pangya.game.player.ItemUcc /** @@ -91,6 +93,16 @@ open class PlayerInventoryItem( */ val STATS: TableField = createField(DSL.name("stats"), SQLDataType.JSON, this, "", JSONtoJacksonConverter(IntArray::class.java)) + /** + * The column public.player_inventory_item.ucc. + */ + val UCC: TableField = createField(DSL.name("ucc"), SQLDataType.JSON, this, "", JSONtoJacksonConverter(ItemUcc::class.java)) + + /** + * The column public.player_inventory_item.club_workshop. + */ + val CLUB_WORKSHOP: TableField = createField(DSL.name("club_workshop"), SQLDataType.JSON, this, "", JSONtoJacksonConverter(ItemClubWorkshop::class.java)) + private constructor(alias: Name, aliased: Table?): this(alias, null, null, aliased, null) private constructor(alias: Name, aliased: Table?, parameters: Array?>?): this(alias, null, null, aliased, parameters) @@ -151,18 +163,18 @@ open class PlayerInventoryItem( override fun rename(name: Table<*>): PlayerInventoryItem = PlayerInventoryItem(name.getQualifiedName(), null) // ------------------------------------------------------------------------- - // Row5 type methods + // Row7 type methods // ------------------------------------------------------------------------- - override fun fieldsRow(): Row5 = super.fieldsRow() as Row5 + override fun fieldsRow(): Row7 = super.fieldsRow() as Row7 /** * Convenience mapping calling {@link SelectField#convertFrom(Function)}. */ - fun mapping(from: (Int?, Int?, Int?, Int?, IntArray?) -> U): SelectField = convertFrom(Records.mapping(from)) + fun mapping(from: (Int?, Int?, Int?, Int?, IntArray?, ItemUcc?, ItemClubWorkshop?) -> U): SelectField = convertFrom(Records.mapping(from)) /** * Convenience mapping calling {@link SelectField#convertFrom(Class, * Function)}. */ - fun mapping(toType: Class, from: (Int?, Int?, Int?, Int?, IntArray?) -> U): SelectField = convertFrom(toType, Records.mapping(from)) + fun mapping(toType: Class, from: (Int?, Int?, Int?, Int?, IntArray?, ItemUcc?, ItemClubWorkshop?) -> U): SelectField = convertFrom(toType, Records.mapping(from)) } diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/records/PlayerInventoryItemRecord.kt b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/records/PlayerInventoryItemRecord.kt index 8ead844..50779af 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/records/PlayerInventoryItemRecord.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/persistence/jooq/tables/records/PlayerInventoryItemRecord.kt @@ -6,18 +6,20 @@ package work.fking.pangya.game.persistence.jooq.tables.records import org.jooq.Field import org.jooq.Record1 -import org.jooq.Record5 -import org.jooq.Row5 +import org.jooq.Record7 +import org.jooq.Row7 import org.jooq.impl.UpdatableRecordImpl import work.fking.pangya.game.persistence.jooq.tables.PlayerInventoryItem +import work.fking.pangya.game.player.ItemClubWorkshop +import work.fking.pangya.game.player.ItemUcc /** * This class is generated by jOOQ. */ @Suppress("UNCHECKED_CAST") -open class PlayerInventoryItemRecord private constructor() : UpdatableRecordImpl(PlayerInventoryItem.PLAYER_INVENTORY_ITEM), Record5 { +open class PlayerInventoryItemRecord private constructor() : UpdatableRecordImpl(PlayerInventoryItem.PLAYER_INVENTORY_ITEM), Record7 { open var uid: Int? set(value): Unit = set(0, value) @@ -39,6 +41,14 @@ open class PlayerInventoryItemRecord private constructor() : UpdatableRecordImpl set(value): Unit = set(4, value) get(): IntArray? = get(4) as IntArray? + open var ucc: ItemUcc? + set(value): Unit = set(5, value) + get(): ItemUcc? = get(5) as ItemUcc? + + open var clubWorkshop: ItemClubWorkshop? + set(value): Unit = set(6, value) + get(): ItemClubWorkshop? = get(6) as ItemClubWorkshop? + // ------------------------------------------------------------------------- // Primary key information // ------------------------------------------------------------------------- @@ -46,26 +56,32 @@ open class PlayerInventoryItemRecord private constructor() : UpdatableRecordImpl override fun key(): Record1 = super.key() as Record1 // ------------------------------------------------------------------------- - // Record5 type implementation + // Record7 type implementation // ------------------------------------------------------------------------- - override fun fieldsRow(): Row5 = super.fieldsRow() as Row5 - override fun valuesRow(): Row5 = super.valuesRow() as Row5 + override fun fieldsRow(): Row7 = super.fieldsRow() as Row7 + override fun valuesRow(): Row7 = super.valuesRow() as Row7 override fun field1(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.UID override fun field2(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.ACCOUNT_UID override fun field3(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.IFF_ID override fun field4(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.QUANTITY override fun field5(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.STATS + override fun field6(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.UCC + override fun field7(): Field = PlayerInventoryItem.PLAYER_INVENTORY_ITEM.CLUB_WORKSHOP override fun component1(): Int? = uid override fun component2(): Int = accountUid override fun component3(): Int = iffId override fun component4(): Int? = quantity override fun component5(): IntArray? = stats + override fun component6(): ItemUcc? = ucc + override fun component7(): ItemClubWorkshop? = clubWorkshop override fun value1(): Int? = uid override fun value2(): Int = accountUid override fun value3(): Int = iffId override fun value4(): Int? = quantity override fun value5(): IntArray? = stats + override fun value6(): ItemUcc? = ucc + override fun value7(): ItemClubWorkshop? = clubWorkshop override fun value1(value: Int?): PlayerInventoryItemRecord { set(0, value) @@ -92,24 +108,38 @@ open class PlayerInventoryItemRecord private constructor() : UpdatableRecordImpl return this } - override fun values(value1: Int?, value2: Int?, value3: Int?, value4: Int?, value5: IntArray?): PlayerInventoryItemRecord { + override fun value6(value: ItemUcc?): PlayerInventoryItemRecord { + set(5, value) + return this + } + + override fun value7(value: ItemClubWorkshop?): PlayerInventoryItemRecord { + set(6, value) + return this + } + + override fun values(value1: Int?, value2: Int?, value3: Int?, value4: Int?, value5: IntArray?, value6: ItemUcc?, value7: ItemClubWorkshop?): PlayerInventoryItemRecord { this.value1(value1) this.value2(value2) this.value3(value3) this.value4(value4) this.value5(value5) + this.value6(value6) + this.value7(value7) return this } /** * Create a detached, initialised PlayerInventoryItemRecord */ - constructor(uid: Int? = null, accountUid: Int, iffId: Int, quantity: Int? = null, stats: IntArray? = null): this() { + constructor(uid: Int? = null, accountUid: Int, iffId: Int, quantity: Int? = null, stats: IntArray? = null, ucc: ItemUcc? = null, clubWorkshop: ItemClubWorkshop? = null): this() { this.uid = uid this.accountUid = accountUid this.iffId = iffId this.quantity = quantity this.stats = stats + this.ucc = ucc + this.clubWorkshop = clubWorkshop resetChangedOnNotNull() } } diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/player/Item.kt b/game-server/src/main/kotlin/work/fking/pangya/game/player/Item.kt index d8a09cf..6a2a173 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/player/Item.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/player/Item.kt @@ -11,7 +11,10 @@ class Item( override val uid: Int = -1, override val iffId: Int, var quantity: Int = 0, - val stats: IntArray = IntArray(5) + val stats: IntArray = IntArray(5), + val cards: IntArray = IntArray(12), + var ucc: ItemUcc = nullItemUcc(), + var clubWorkshop: ItemClubWorkshop = nullItemClubWorkshop() ) : IffObject { fun quantifiable(): Boolean { @@ -33,7 +36,11 @@ class Item( } else { stats.forEach { buffer.writeShortLE(it) } } - writeZero(174) + writeZero(19) + + write(ucc) + cards.forEach { writeIntLE(it) } + write(clubWorkshop) } } @@ -59,3 +66,4 @@ class Item( return uid } } + diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemClubWorkshop.kt b/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemClubWorkshop.kt new file mode 100644 index 0000000..a06ae26 --- /dev/null +++ b/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemClubWorkshop.kt @@ -0,0 +1,29 @@ +package work.fking.pangya.game.player + +import io.netty.buffer.ByteBuf + +class ItemClubWorkshop( + val stats: IntArray = IntArray(5), + val mastery: Int, + val usedRecoveryPoints: Int, + val level: Int, + val rank: Int +) + +fun ByteBuf.write(clubWorkshop: ItemClubWorkshop) { + with(clubWorkshop) { + writeShortLE(0) // unknown + stats.forEach { writeShortLE(it) } + writeIntLE(mastery) + writeIntLE(usedRecoveryPoints) + writeIntLE(level) // level? client seems to completely ignore it and just compute it + writeIntLE(rank) // rank? client seems to completely ignore it and just compute it + } +} + +fun nullItemClubWorkshop() = ItemClubWorkshop( + mastery = 0, + usedRecoveryPoints = 0, + level = 0, + rank = 0 +) \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemUcc.kt b/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemUcc.kt new file mode 100644 index 0000000..a558635 --- /dev/null +++ b/game-server/src/main/kotlin/work/fking/pangya/game/player/ItemUcc.kt @@ -0,0 +1,24 @@ +package work.fking.pangya.game.player + +import io.netty.buffer.ByteBuf +import work.fking.pangya.networking.protocol.writeFixedSizeString + +class ItemUcc(val unknown: Int, val id: String, val name: String, val copiedFrom: String, val copiedFromUid: Int) + +fun ByteBuf.write(ucc: ItemUcc) { + writeFixedSizeString(ucc.name, 40) // name + writeByte(0) + writeFixedSizeString(ucc.id, 9) // string id (this is what the client will request from the webserver) + writeByte(ucc.unknown) // if this is not 1, client does not init the ucc + writeZero(2) + writeFixedSizeString(ucc.copiedFrom, 22) // the name of who created this copy + writeIntLE(ucc.copiedFromUid) // the uid of who created this copy +} + +fun nullItemUcc() = ItemUcc( + unknown = 0, + id = "", + name = "", + copiedFrom = "", + copiedFromUid = 0 +) \ No newline at end of file diff --git a/game-server/src/main/kotlin/work/fking/pangya/game/task/ChangeClubSetStatTask.kt b/game-server/src/main/kotlin/work/fking/pangya/game/task/ChangeClubSetStatTask.kt index 8168e23..869bd73 100644 --- a/game-server/src/main/kotlin/work/fking/pangya/game/task/ChangeClubSetStatTask.kt +++ b/game-server/src/main/kotlin/work/fking/pangya/game/task/ChangeClubSetStatTask.kt @@ -3,6 +3,10 @@ package work.fking.pangya.game.task import work.fking.pangya.game.model.IFF_TYPE_CLUBSET import work.fking.pangya.game.model.iffTypeFromId import work.fking.pangya.game.packet.outbound.ClubSetReplies +import work.fking.pangya.game.packet.outbound.ClubSetReplies.UpgradeResult.CANNOT_DOWNGRADE_ANYMORE +import work.fking.pangya.game.packet.outbound.ClubSetReplies.UpgradeResult.DOWNGRADE_SUCCESS +import work.fking.pangya.game.packet.outbound.ClubSetReplies.UpgradeResult.INSUFFICIENT_PANG +import work.fking.pangya.game.packet.outbound.ClubSetReplies.UpgradeResult.UPGRADE_SUCCESS import work.fking.pangya.game.persistence.PersistenceContext import work.fking.pangya.game.player.Item import work.fking.pangya.game.player.Player @@ -45,7 +49,10 @@ class ChangeClubSetStatTask( SPIN, CURVE -> 1900 } val wallet = player.wallet - require(wallet.pangBalance >= cost) { "Player ${player.nickname} tried to upgrade an item but doesn't have enough pang" } + + if (wallet.pangBalance < cost) { + player.writeAndFlush(ClubSetReplies.upgradeAck(result = INSUFFICIENT_PANG, stat = stat.ordinal, itemUid = itemUid)) + } // TODO: verify clubset upgrade limits persistenceCtx.transactional { tx -> @@ -54,15 +61,18 @@ class ChangeClubSetStatTask( persistenceCtx.playerRepository.saveWallet(tx, player.uid, wallet) persistenceCtx.inventoryRepository.saveItem(tx, player.uid, clubSet) } - player.writeAndFlush(ClubSetReplies.upgradeAck(type, stat.ordinal, itemUid, cost)) + player.writeAndFlush(ClubSetReplies.upgradeAck(result = UPGRADE_SUCCESS, stat = stat.ordinal, itemUid = itemUid, cost = cost)) } private fun downgrade(clubSet: Item) { - require(clubSet.stats[stat.ordinal] > 0) { "Player ${player.nickname} tried to downgrade an item but the stat is already at 0" } + if (clubSet.stats[stat.ordinal] <= 0) { + player.writeAndFlush(ClubSetReplies.upgradeAck(result = CANNOT_DOWNGRADE_ANYMORE, stat = stat.ordinal, itemUid = itemUid)) + return + } clubSet.stats[stat.ordinal]-- persistenceCtx.inventoryRepository.saveItem(persistenceCtx.noTxContext(), player.uid, clubSet) - player.writeAndFlush(ClubSetReplies.upgradeAck(type, stat.ordinal, itemUid, 0)) + player.writeAndFlush(ClubSetReplies.upgradeAck(result = DOWNGRADE_SUCCESS, stat = stat.ordinal, itemUid = itemUid)) } } diff --git a/jooq.xml b/jooq.xml index e5b4bf2..076dc46 100644 --- a/jooq.xml +++ b/jooq.xml @@ -6,10 +6,26 @@ org.jooq.meta.postgres.PostgresDatabase public + + work.fking.pangya.game.player.ItemUcc + ucc + true + JSON + COLUMN + + + work.fking.pangya.game.player.ItemClubWorkshop + club_workshop + true + JSON + COLUMN + kotlin.IntArray + .*_parts|.*_ids|.*_uids|cards|stats true JSON + COLUMN