├── Start Server.bat ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src ├── main │ ├── java │ │ └── emu │ │ │ └── nebula │ │ │ ├── game │ │ │ ├── dating │ │ │ │ ├── DatingEvent.java │ │ │ │ ├── DatingGame.java │ │ │ │ ├── DatingEventType.java │ │ │ │ └── DatingManager.java │ │ │ ├── quest │ │ │ │ ├── QuestData.java │ │ │ │ └── QuestType.java │ │ │ ├── GameContextModule.java │ │ │ ├── gacha │ │ │ │ ├── GachaResult.java │ │ │ │ └── GachaHistoryLog.java │ │ │ ├── inventory │ │ │ │ ├── ItemRewardList.java │ │ │ │ ├── ItemRewardParam.java │ │ │ │ ├── UseMode.java │ │ │ │ ├── UseAction.java │ │ │ │ ├── ItemParam.java │ │ │ │ └── ItemType.java │ │ │ ├── player │ │ │ │ └── PlayerManager.java │ │ │ ├── tower │ │ │ │ ├── StarTowerPotentialInfo.java │ │ │ │ ├── room │ │ │ │ │ ├── StarTowerBattleRoom.java │ │ │ │ │ ├── StarTowerEventRoom.java │ │ │ │ │ ├── RoomType.java │ │ │ │ │ └── StarTowerHawkerRoom.java │ │ │ │ └── cases │ │ │ │ │ ├── StarTowerSyncHPCase.java │ │ │ │ │ ├── StarTowerRecoveryHPCase.java │ │ │ │ │ ├── StarTowerNpcRecoveryHPCase.java │ │ │ │ │ └── CaseType.java │ │ │ ├── story │ │ │ │ └── StoryChoiceInfo.java │ │ │ ├── instance │ │ │ │ └── InstanceSettleData.java │ │ │ ├── battlepass │ │ │ │ └── BattlePassManager.java │ │ │ ├── tutorial │ │ │ │ └── TutorialLevelLog.java │ │ │ ├── agent │ │ │ │ └── AgentResult.java │ │ │ ├── activity │ │ │ │ ├── ActivityType.java │ │ │ │ └── ActivityModule.java │ │ │ ├── vampire │ │ │ │ └── VampireSurvivorLog.java │ │ │ └── character │ │ │ │ └── ElementType.java │ │ │ ├── database │ │ │ ├── AccountDatabaseOnly.java │ │ │ ├── GameDatabaseObject.java │ │ │ └── DatabaseCounter.java │ │ │ ├── net │ │ │ ├── HandlerId.java │ │ │ ├── NetHandler.java │ │ │ └── NetMsgPacket.java │ │ │ ├── data │ │ │ ├── BaseDef.java │ │ │ ├── resources │ │ │ │ ├── DatingCharacterEventDef.java │ │ │ │ ├── BattlePassDef.java │ │ │ │ ├── ResidentShopDef.java │ │ │ │ ├── HonorDef.java │ │ │ │ ├── StoryEvidenceDef.java │ │ │ │ ├── DiscItemExpDef.java │ │ │ │ ├── GuideGroupDef.java │ │ │ │ ├── CharItemExpDef.java │ │ │ │ ├── DiscStrengthenDef.java │ │ │ │ ├── CharacterUpgradeDef.java │ │ │ │ ├── HandbookDef.java │ │ │ │ ├── StarTowerBookFateCardQuestDef.java │ │ │ │ ├── ActivityShopControlDef.java │ │ │ │ ├── CharacterSkinDef.java │ │ │ │ ├── VampireTalentDef.java │ │ │ │ ├── AffinityLevelDef.java │ │ │ │ ├── AffinityGiftDef.java │ │ │ │ ├── InfinityTowerDifficultyDef.java │ │ │ │ ├── StarTowerBuildRankDef.java │ │ │ │ ├── CharGemDef.java │ │ │ │ ├── PlayerHeadDef.java │ │ │ │ ├── BattlePassLevelDef.java │ │ │ │ ├── ScoreBossRewardDef.java │ │ │ │ ├── StarTowerTeamExpDef.java │ │ │ │ ├── TrialControlDef.java │ │ │ │ ├── TutorialLevelDef.java │ │ │ │ ├── SignInDef.java │ │ │ │ ├── ScoreBossControlDef.java │ │ │ │ ├── MainScreenCGDef.java │ │ │ │ ├── DiscPromoteLimitDef.java │ │ │ │ ├── StarTowerGrowthNodeDef.java │ │ │ │ ├── StarTowerFloorExpDef.java │ │ │ │ ├── MallGemDef.java │ │ │ │ ├── DictionaryTabDef.java │ │ │ │ ├── CharPotentialDef.java │ │ │ │ ├── MallMonthlyCardDef.java │ │ │ │ ├── ActivityDef.java │ │ │ │ ├── FateCardDef.java │ │ │ │ ├── SubNoteSkillPromoteGroupDef.java │ │ │ │ ├── GachaStorageDef.java │ │ │ │ ├── TalentGroupDef.java │ │ │ │ ├── TitleDef.java │ │ │ │ ├── ActivityShopDef.java │ │ │ │ ├── PlotDef.java │ │ │ │ ├── WorldClassDef.java │ │ │ │ ├── DictionaryEntryDef.java │ │ │ │ ├── StarTowerBookFateCardBundleDef.java │ │ │ │ ├── DatingBranchDef.java │ │ │ │ ├── VampireSurvivorDef.java │ │ │ │ ├── StarTowerStageDef.java │ │ │ │ ├── MallPackageDef.java │ │ │ │ ├── TowerDefenseLevelDef.java │ │ │ │ ├── ProductionDef.java │ │ │ │ ├── StarTowerEventDef.java │ │ │ │ ├── StoryDef.java │ │ │ │ ├── EventOptionsDef.java │ │ │ │ ├── ChatDef.java │ │ │ │ ├── DiscDef.java │ │ │ │ ├── StarTowerDef.java │ │ │ │ ├── TalentDef.java │ │ │ │ ├── ActivityTaskDef.java │ │ │ │ ├── DailyQuestActiveDef.java │ │ │ │ ├── StarTowerBookFateCardDef.java │ │ │ │ ├── TrialGroupDef.java │ │ │ │ ├── ActivityGoodsDef.java │ │ │ │ ├── ResidentGoodsDef.java │ │ │ │ ├── StorySetSectionDef.java │ │ │ │ ├── GachaPkgDef.java │ │ │ │ ├── CharGemAttrValueDef.java │ │ │ │ ├── MallShopDef.java │ │ │ │ ├── DropPkgDef.java │ │ │ │ └── BattlePassRewardDef.java │ │ │ ├── custom │ │ │ │ └── AchievementParamDef.java │ │ │ └── ResourceType.java │ │ │ ├── util │ │ │ ├── ints │ │ │ │ ├── IntBiPredicate.java │ │ │ │ ├── String2IntMap.java │ │ │ │ └── CustomIntArray.java │ │ │ ├── Snowflake.java │ │ │ ├── WeightedList.java │ │ │ └── FileUtils.java │ │ │ ├── command │ │ │ ├── CommandHandler.java │ │ │ ├── Command.java │ │ │ ├── CommandResult.java │ │ │ └── commands │ │ │ │ ├── ReloadCommand.java │ │ │ │ └── RemoteKeyCommand.java │ │ │ └── server │ │ │ ├── handlers │ │ │ ├── HandlerPlayerMusicSetReq.java │ │ │ ├── Handler.java │ │ │ ├── HandlerGachaNewbieSpinReq.java │ │ │ ├── HandlerVampireTalentShowReq.java │ │ │ ├── HandlerPlayerGenderEditReq.java │ │ │ ├── HandlerActivityTowerDefenseLevelApplyReq.java │ │ │ ├── HandlerAchievementInfoReq.java │ │ │ ├── HandlerVampireTalentResetReq.java │ │ │ ├── HandlerBattlePassInfoReq.java │ │ │ ├── HandlerPlayerPingReq.java │ │ │ ├── HandlerGachaNewbieObtainReq.java │ │ │ ├── HandlerPlayerLearnReq.java │ │ │ ├── HandlerMailListReq.java │ │ │ ├── HandlerFriendListGetReq.java │ │ │ ├── HandlerClientEventReportReq.java │ │ │ ├── HandlerPlayerNameEditReq.java │ │ │ ├── HandlerStoryApplyReq.java │ │ │ ├── HandlerPlayerFormationReq.java │ │ │ ├── HandlerTowerGrowthDetailReq.java │ │ │ ├── HandlerFriendStarSetReq.java │ │ │ ├── HandlerPlayerBoardSetReq.java │ │ │ ├── HandlerPlayerDataReq.java │ │ │ ├── HandlerDailyShopRewardReceiveReq.java │ │ │ ├── HandlerFriendDeleteReq.java │ │ │ ├── HandlerPlayerCharsShowReq.java │ │ │ ├── HandlerActivityDetailReq.java │ │ │ ├── HandlerPlayerTitleEditReq.java │ │ │ ├── HandlerFriendAddReq.java │ │ │ ├── HandlerGachaInformationReq.java │ │ │ ├── HandlerVampireTalentUnlockReq.java │ │ │ ├── HandlerPlayerHeadIconSetReq.java │ │ │ ├── HandlerScoreBossApplyReq.java │ │ │ ├── HandlerGachaNewbieInfoReq.java │ │ │ ├── HandlerPhoneContactsInfoReq.java │ │ │ ├── HandlerStorySetRewardReceiveReq.java │ │ │ ├── HandlerPlayerHeadIconInfoReq.java │ │ │ ├── HandlerMailReadReq.java │ │ │ ├── HandlerGemConvertReq.java │ │ │ ├── HandlerFriendInvitesDeleteReq.java │ │ │ ├── HandlerScoreBossStarRewardReceiveReq.java │ │ │ ├── HandlerPlayerSkinShowReq.java │ │ │ ├── HandlerItemProductReq.java │ │ │ ├── HandlerStorySettleReq.java │ │ │ ├── HandlerMallGemListReq.java │ │ │ ├── HandlerQuestDailyRewardReceiveReq.java │ │ │ ├── HandlerTowerGrowthNodeUnlockReq.java │ │ │ ├── HandlerTutorialLevelSettleReq.java │ │ │ ├── HandlerVampireTalentDetailReq.java │ │ │ ├── HandlerInfinityTowerApplyReq.java │ │ │ ├── HandlerStarTowerBuildBriefListGetReq.java │ │ │ ├── HandlerGachaGuaranteeRewardReceiveReq.java │ │ │ ├── HandlerPhoneContactsTopReq.java │ │ │ ├── HandlerMallPackageListReq.java │ │ │ ├── HandlerAchievementRewardReceiveReq.java │ │ │ ├── HandlerFriendRecommendationGetReq.java │ │ │ ├── HandlerMallMonthlyCardListReq.java │ │ │ ├── HandlerTutorialLevelRewardReceiveReq.java │ │ │ ├── HandlerMailRemoveReq.java │ │ │ ├── HandlerStarTowerInteractReq.java │ │ │ ├── HandlerTowerBookFateCardDetailReq.java │ │ │ ├── HandlerPlayerWorldClassRewardReceiveReq.java │ │ │ ├── HandlerStarTowerBuildLockUnlockReq.java │ │ │ ├── HandlerCharAdvanceReq.java │ │ │ ├── HandlerWeekBossApplyReq.java │ │ │ ├── HandlerGachaHistoriesReq.java │ │ │ ├── HandlerStarTowerGiveUpReq.java │ │ │ ├── HandlerAgentGiveUpReq.java │ │ │ ├── HandlerSkillInstanceApplyReq.java │ │ │ ├── HandlerCharSkinSetReq.java │ │ │ ├── HandlerCharGemInstanceApplyReq.java │ │ │ ├── HandlerEnergyBuyReq.java │ │ │ ├── HandlerRegionBossLevelApplyReq.java │ │ │ ├── HandlerFriendAllAgreeReq.java │ │ │ ├── HandlerMailPinReq.java │ │ │ ├── HandlerFriendAddAgreeReq.java │ │ │ ├── HandlerCharGemUsePresetReq.java │ │ │ ├── HandlerCharSkillUpgradeReq.java │ │ │ ├── HandlerFriendUidSearchReq.java │ │ │ └── HandlerMallShopOrderReq.java │ │ │ ├── routes │ │ │ ├── HttpJsonResponse.java │ │ │ └── MetaPatchListHandler.java │ │ │ ├── error │ │ │ └── ServerException.java │ │ │ └── PatchList.java │ └── resources │ │ └── logback.xml └── generated │ └── main │ └── emu │ └── nebula │ └── proto │ ├── MailList.java │ ├── MailRead.java │ ├── GemConvert.java │ ├── PlayerExit.java │ ├── CharAdvance.java │ ├── EnergyExtract.java │ ├── PlayerLearn.java │ ├── StarTowerInfo.java │ ├── AchievementInfo.java │ ├── ActivityCgRead.java │ ├── CharRecruitment.java │ ├── MallOrderCancel.java │ ├── PlayerMusicSet.java │ ├── ClientEventReport.java │ ├── FragmentsConvert.java │ ├── JointDrillGameOver.java │ ├── JointDrillRetreat.java │ ├── MallOrderCollect.java │ ├── PhoneContactsTop.java │ ├── PlayerGenderEdit.java │ ├── PlotRewardReceive.java │ ├── VampireTalentReset.java │ ├── VampireTalentShow.java │ ├── MallMonthlycardOrder.java │ ├── TutorialLevelSettle.java │ ├── VampireTalentUnlock.java │ ├── DailyShopRewardReceive.java │ ├── PlayerWorldCalssAdvance.java │ ├── QuestDailyRewardRecevie.java │ ├── QuestTowerRewardRecevie.java │ ├── TowerGrowthNodeUnlock.java │ ├── VampireSurvivorRestart.java │ ├── ActivityLoginRewardReceive.java │ ├── GachaGuaranteeRewardReceive.java │ ├── JointDrillQuestRewardReceive.java │ ├── TutorialLevelRewardReceive.java │ ├── ActivityTaskGroupRewardReceive.java │ ├── VampireSurvivorExtraRewardSelect.java │ ├── ActivityPeriodicFinalRewardReceive.java │ └── ActivityTowerDefenseStoryRewardReceive.java ├── settings.gradle ├── .github └── workflows │ └── gradle.yml └── .gitignore /Start Server.bat: -------------------------------------------------------------------------------- 1 | java -jar Nebula.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Melledy/Nebula/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/dating/DatingEvent.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.dating; 2 | 3 | public interface DatingEvent { 4 | 5 | public int getId(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/MailList.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class MailList { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/MailRead.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class MailRead { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/GemConvert.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class GemConvert { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlayerExit.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlayerExit { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/CharAdvance.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class CharAdvance { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/EnergyExtract.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class EnergyExtract { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlayerLearn.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlayerLearn { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/StarTowerInfo.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class StarTowerInfo { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/AchievementInfo.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class AchievementInfo { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ActivityCgRead.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ActivityCgRead { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/CharRecruitment.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class CharRecruitment { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/MallOrderCancel.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class MallOrderCancel { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlayerMusicSet.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlayerMusicSet { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ClientEventReport.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ClientEventReport { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/FragmentsConvert.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class FragmentsConvert { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/JointDrillGameOver.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class JointDrillGameOver { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/JointDrillRetreat.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class JointDrillRetreat { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/MallOrderCollect.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class MallOrderCollect { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PhoneContactsTop.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PhoneContactsTop { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlayerGenderEdit.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlayerGenderEdit { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlotRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlotRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/VampireTalentReset.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class VampireTalentReset { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/VampireTalentShow.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class VampireTalentShow { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/MallMonthlycardOrder.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class MallMonthlycardOrder { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/TutorialLevelSettle.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class TutorialLevelSettle { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/VampireTalentUnlock.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class VampireTalentUnlock { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/DailyShopRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class DailyShopRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/PlayerWorldCalssAdvance.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class PlayerWorldCalssAdvance { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/QuestDailyRewardRecevie.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class QuestDailyRewardRecevie { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/QuestTowerRewardRecevie.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class QuestTowerRewardRecevie { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/TowerGrowthNodeUnlock.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class TowerGrowthNodeUnlock { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/VampireSurvivorRestart.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class VampireSurvivorRestart { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ActivityLoginRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ActivityLoginRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/GachaGuaranteeRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class GachaGuaranteeRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/JointDrillQuestRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class JointDrillQuestRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/TutorialLevelRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class TutorialLevelRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ActivityTaskGroupRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ActivityTaskGroupRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/VampireSurvivorExtraRewardSelect.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class VampireSurvivorExtraRewardSelect { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ActivityPeriodicFinalRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ActivityPeriodicFinalRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/generated/main/emu/nebula/proto/ActivityTowerDefenseStoryRewardReceive.java: -------------------------------------------------------------------------------- 1 | // Code generated by protocol buffer compiler. Do not edit! 2 | package emu.nebula.proto; 3 | 4 | public final class ActivityTowerDefenseStoryRewardReceive { 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/database/AccountDatabaseOnly.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.database; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface AccountDatabaseOnly { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/net/HandlerId.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.net; 2 | 3 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 4 | 5 | import java.lang.annotation.Retention; 6 | 7 | @Retention(RUNTIME) 8 | public @interface HandlerId { 9 | public int value(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/database/GameDatabaseObject.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.database; 2 | 3 | import emu.nebula.Nebula; 4 | 5 | public interface GameDatabaseObject { 6 | 7 | public default void save() { 8 | Nebula.getGameDatabase().save(this); 9 | } 10 | 11 | } 12 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/quest/QuestData.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.quest; 2 | 3 | public interface QuestData { 4 | 5 | public int getId(); 6 | 7 | public int getQuestType(); 8 | 9 | public int getCompleteCond(); 10 | 11 | public int[] getCompleteCondParams(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/BaseDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data; 2 | 3 | public abstract class BaseDef implements Comparable { 4 | 5 | public abstract int getId(); 6 | 7 | public void onLoad() { 8 | 9 | } 10 | 11 | @Override 12 | public int compareTo(BaseDef o) { 13 | return this.getId() - o.getId(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/GameContextModule.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game; 2 | 3 | public abstract class GameContextModule { 4 | private transient GameContext context; 5 | 6 | public GameContextModule(GameContext player) { 7 | this.context = player; 8 | } 9 | 10 | public GameContext getGameContext() { 11 | return context; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/5.6.3/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = 'Nebula' 11 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/ints/IntBiPredicate.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util.ints; 2 | 3 | import java.util.function.BiPredicate; 4 | 5 | public interface IntBiPredicate extends BiPredicate{ 6 | 7 | @Deprecated 8 | @Override 9 | default boolean test(Integer t, Integer u) { 10 | return test(t, u); 11 | } 12 | 13 | public boolean test(int t, int u); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DatingCharacterEventDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.ResourceType; 4 | import emu.nebula.data.ResourceType.LoadPriority; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "DatingCharacterEvent.json", loadPriority = LoadPriority.LOW) 9 | public class DatingCharacterEventDef extends DatingLandmarkEventDef { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/net/NetHandler.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.net; 2 | 3 | public abstract class NetHandler { 4 | 5 | public boolean requireSession() { 6 | return true; 7 | } 8 | 9 | public boolean requirePlayer() { 10 | return true; 11 | } 12 | 13 | // Handler 14 | 15 | public abstract byte[] handle(GameSession session, byte[] message) throws Exception; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/command/CommandHandler.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.command; 2 | 3 | public interface CommandHandler { 4 | 5 | public default Command getData() { 6 | return this.getClass().getAnnotation(Command.class); 7 | } 8 | 9 | public default String getLabel() { 10 | return getData().label(); 11 | } 12 | 13 | public String execute(CommandArgs args); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/BattlePassDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "BattlePass.json") 9 | public class BattlePassDef extends BaseDef { 10 | private int ID; 11 | 12 | @Override 13 | public int getId() { 14 | return ID; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ResidentShopDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "ResidentShop.json") 9 | public class ResidentShopDef extends BaseDef { 10 | private int Id; 11 | 12 | @Override 13 | public int getId() { 14 | return Id; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/HonorDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "Honor.json") 9 | public class HonorDef extends BaseDef { 10 | private int Id; 11 | private int Type; 12 | 13 | @Override 14 | public int getId() { 15 | return Id; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StoryEvidenceDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "StoryEvidence.json") 10 | public class StoryEvidenceDef extends BaseDef { 11 | private int Id; 12 | 13 | @Override 14 | public int getId() { 15 | return Id; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DiscItemExpDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "DiscItemExp.json") 9 | public class DiscItemExpDef extends BaseDef { 10 | private int ItemId; 11 | private int Exp; 12 | 13 | @Override 14 | public int getId() { 15 | return ItemId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/GuideGroupDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "GuideGroup.json") 9 | public class GuideGroupDef extends BaseDef { 10 | private int Id; 11 | private boolean IsActive; 12 | 13 | @Override 14 | public int getId() { 15 | return Id; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharItemExpDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "CharItemExp.json") 9 | public class CharItemExpDef extends BaseDef { 10 | private int ItemId; 11 | private int ExpValue; 12 | 13 | @Override 14 | public int getId() { 15 | return ItemId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DiscStrengthenDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "DiscStrengthen.json") 10 | public class DiscStrengthenDef extends BaseDef { 11 | private int Id; 12 | private int Exp; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharacterUpgradeDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "CharacterUpgrade.json") 9 | public class CharacterUpgradeDef extends BaseDef { 10 | private int Level; 11 | private int Exp; 12 | 13 | @Override 14 | public int getId() { 15 | return Level; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/HandbookDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "Handbook.json") 9 | public class HandbookDef extends BaseDef { 10 | private int Id; 11 | private int Index; 12 | private int Type; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerBookFateCardQuestDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "StarTowerBookFateCardQuest.json") 9 | public class StarTowerBookFateCardQuestDef extends BaseDef { 10 | private int Id; 11 | 12 | @Override 13 | public int getId() { 14 | return Id; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ActivityShopControlDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "ActivityShopControl.json") 10 | public class ActivityShopControlDef extends BaseDef { 11 | private int Id; 12 | private int[] ShopIds; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharacterSkinDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "CharacterSkin.json") 9 | public class CharacterSkinDef extends BaseDef { 10 | private int Id; 11 | private int CharId; 12 | private int Type; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/VampireTalentDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "VampireTalent.json") 9 | public class VampireTalentDef extends BaseDef { 10 | private int Id; 11 | private int[] Prev; 12 | private int Point; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/AffinityLevelDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "AffinityLevel.json") 10 | public class AffinityLevelDef extends BaseDef { 11 | private int AffinityLevel; 12 | private int NeedExp; 13 | 14 | @Override 15 | public int getId() { 16 | return AffinityLevel; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/ints/String2IntMap.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util.ints; 2 | 3 | import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; 4 | 5 | public class String2IntMap extends Object2IntOpenHashMap { 6 | private static final long serialVersionUID = -7301945177198000055L; 7 | 8 | public int get(String key) { 9 | return super.getInt(key); 10 | } 11 | 12 | public FastEntrySet entries() { 13 | return super.object2IntEntrySet(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/command/Command.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.command; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface Command { 8 | public String label() default ""; 9 | 10 | public String[] aliases() default ""; 11 | 12 | public String desc() default ""; 13 | 14 | public String permission() default ""; 15 | 16 | public boolean requireTarget() default false; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/AffinityGiftDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "AffinityGift.json") 10 | public class AffinityGiftDef extends BaseDef { 11 | private int Id; 12 | private int BaseAffinity; 13 | private int[] Tags; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/InfinityTowerDifficultyDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "InfinityTowerDifficulty.json") 10 | public class InfinityTowerDifficultyDef extends BaseDef { 11 | private int Id; 12 | private int TowerId; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerBuildRankDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "StarTowerBuildRank.json") 9 | public class StarTowerBuildRankDef extends BaseDef { 10 | private int Id; 11 | private int MinGrade; 12 | private int Rarity; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharGemDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "CharGem.json") 9 | public class CharGemDef extends BaseDef { 10 | private int Id; 11 | private int GenerateCostTid; 12 | private int RefreshCostTid; 13 | private int Type; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/PlayerHeadDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "PlayerHead.json") 9 | public class PlayerHeadDef extends BaseDef { 10 | private int Id; 11 | private int HeadType; 12 | private int UnlockChar; 13 | private int UnlockSkin; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/command/CommandResult.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.command; 2 | 3 | import lombok.Builder; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | @Builder 8 | public class CommandResult { 9 | private CommandHandler command; 10 | private String message; 11 | 12 | public boolean isCommandTypeOf(Class handler) { 13 | if (command == null) { 14 | return false; 15 | } 16 | 17 | return command.getClass().equals(handler); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/BattlePassLevelDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "BattlePassLevel.json") 9 | public class BattlePassLevelDef extends BaseDef { 10 | private int ID; 11 | private int Exp; 12 | 13 | private int Tid; 14 | private int Qty; 15 | 16 | @Override 17 | public int getId() { 18 | return ID; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ScoreBossRewardDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "ScoreBossReward.json") 10 | public class ScoreBossRewardDef extends BaseDef { 11 | private int StarNeed; 12 | private int RewardItemId1; 13 | private int RewardNum1; 14 | 15 | @Override 16 | public int getId() { 17 | return StarNeed; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerTeamExpDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "StarTowerTeamExp.json") 9 | public class StarTowerTeamExpDef extends BaseDef { 10 | private int Id; 11 | private int GroupId; 12 | private int Level; 13 | private int NeedExp; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TrialControlDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import it.unimi.dsi.fastutil.ints.IntOpenHashSet; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "TrialControl.json") 10 | public class TrialControlDef extends BaseDef { 11 | private int Id; 12 | private IntOpenHashSet GroupIds; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TutorialLevelDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "TutorialLevel.json") 10 | public class TutorialLevelDef extends BaseDef { 11 | private int Id; 12 | private int WorldClass; 13 | private int Item1; 14 | private int Qty1; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/SignInDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "SignIn.json") 10 | public class SignInDef extends BaseDef { 11 | private int Group; 12 | private int Day; 13 | private int ItemId; 14 | private int ItemQty; 15 | 16 | @Override 17 | public int getId() { 18 | return (this.Group << 16) + this.Day; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ScoreBossControlDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import it.unimi.dsi.fastutil.ints.IntOpenHashSet; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "ScoreBossControl.json") 10 | public class ScoreBossControlDef extends BaseDef { 11 | private int Id; 12 | private IntOpenHashSet LevelGroup; 13 | 14 | @Override 15 | public int getId() { 16 | return Id; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/net/NetMsgPacket.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.net; 2 | 3 | import lombok.Getter; 4 | import us.hebi.quickbuf.ProtoMessage; 5 | 6 | @Getter 7 | public class NetMsgPacket { 8 | private int msgId; 9 | private ProtoMessage proto; 10 | 11 | public NetMsgPacket(int msgId, ProtoMessage proto) { 12 | this.msgId = msgId; 13 | this.proto = proto; 14 | } 15 | 16 | public byte[] toByteArray() { 17 | return PacketHelper.encodeMsg(this.getMsgId(), this.getProto()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/MainScreenCGDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.data.ResourceType.LoadPriority; 6 | 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "MainScreenCG.json", loadPriority = LoadPriority.LOW) 11 | public class MainScreenCGDef extends BaseDef { 12 | private int Id; 13 | private boolean IsShown; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DiscPromoteLimitDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "DiscPromoteLimit.json") 9 | public class DiscPromoteLimitDef extends BaseDef { 10 | private int Id; 11 | private int Rarity; 12 | private int Phase; 13 | private int MaxLevel; 14 | private int WorldClassLimit; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerMusicSetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.player_music_set_req) 9 | public class HandlerPlayerMusicSetReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | return session.encodeMsg(NetMsgId.player_music_set_failed_ack); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerGrowthNodeDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "StarTowerGrowthNode.json") 9 | public class StarTowerGrowthNodeDef extends BaseDef { 10 | private int Id; 11 | private int NodeId; 12 | private int Group; 13 | 14 | private int ItemId1; 15 | private int ItemQty1; 16 | 17 | @Override 18 | public int getId() { 19 | return Id; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/Handler.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.none) 9 | public class Handler extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Template handler 14 | 15 | // Encode and send 16 | return session.encodeMsg(NetMsgId.none); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaNewbieSpinReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.gacha_newbie_spin_req) 9 | public class HandlerGachaNewbieSpinReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | return session.encodeMsg(NetMsgId.gacha_newbie_spin_failed_ack); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/gacha/GachaResult.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.gacha; 2 | 3 | import emu.nebula.game.player.PlayerChangeInfo; 4 | import it.unimi.dsi.fastutil.ints.IntList; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class GachaResult { 9 | private GachaBannerInfo info; 10 | private PlayerChangeInfo change; 11 | private IntList cards; 12 | 13 | public GachaResult(GachaBannerInfo info, PlayerChangeInfo change, IntList cards) { 14 | this.info = info; 15 | this.change = change; 16 | this.cards = cards; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/database/DatabaseCounter.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.database; 2 | 3 | import dev.morphia.annotations.Entity; 4 | import dev.morphia.annotations.Id; 5 | 6 | @Entity(value = "counters", useDiscriminator = false) 7 | public class DatabaseCounter { 8 | @Id 9 | private String id; 10 | private int count; 11 | 12 | public DatabaseCounter() {} 13 | 14 | public DatabaseCounter(String id) { 15 | this.id = id; 16 | this.count = 10000; 17 | } 18 | 19 | public int getNextId() { 20 | int id = ++count; 21 | return id; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/ItemRewardList.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class ItemRewardList extends ArrayList { 6 | private static final long serialVersionUID = -4317949564663392685L; 7 | 8 | public ItemRewardList() { 9 | super(); 10 | } 11 | 12 | public ItemParamMap generate() { 13 | var map = new ItemParamMap(); 14 | 15 | for (var param : this) { 16 | map.add(param.getId(), param.getRandomCount()); 17 | } 18 | 19 | return map; 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerVampireTalentShowReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.vampire_talent_show_req) 9 | public class HandlerVampireTalentShowReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Encode and send 14 | return session.encodeMsg(NetMsgId.vampire_talent_show_succeed_ack); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerFloorExpDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "StarTowerFloorExp.json") 9 | public class StarTowerFloorExpDef extends BaseDef { 10 | private int Id; 11 | private int StarTowerId; 12 | private int Stage; 13 | private int NormalExp; 14 | private int EliteExp; 15 | private int BossExp; 16 | private int FinalBossExp; 17 | 18 | @Override 19 | public int getId() { 20 | return Id; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerGenderEditReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.player_gender_edit_req) 9 | public class HandlerPlayerGenderEditReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | session.getPlayer().editGender(); 14 | 15 | return session.encodeMsg(NetMsgId.player_gender_edit_succeed_ack); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/MallGemDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "MallGem.json") 11 | public class MallGemDef extends BaseDef { 12 | @SerializedName("Id") 13 | private String IdString; 14 | private int Stock; 15 | private int ItemId; 16 | private int CurrencyItemId; 17 | private int ItemQty; 18 | 19 | @Override 20 | public int getId() { 21 | return IdString.hashCode(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/ItemRewardParam.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import emu.nebula.util.Utils; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | public class ItemRewardParam { 8 | public int id; 9 | public int min; 10 | public int max; 11 | 12 | public ItemRewardParam(int id, int min, int max) { 13 | this.id = id; 14 | this.min = min; 15 | this.max = max; 16 | } 17 | 18 | public int getRandomCount() { 19 | if (this.min == this.max) { 20 | return this.min; 21 | } 22 | 23 | return Utils.randomRange(this.min, this.max); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DictionaryTabDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import emu.nebula.data.BaseDef; 7 | import emu.nebula.data.ResourceType; 8 | 9 | import lombok.Getter; 10 | 11 | @Getter 12 | @ResourceType(name = "DictionaryTab.json") 13 | public class DictionaryTabDef extends BaseDef { 14 | private int Id; 15 | 16 | private List entries; 17 | 18 | public DictionaryTabDef() { 19 | this.entries = new ArrayList<>(); 20 | } 21 | 22 | @Override 23 | public int getId() { 24 | return Id; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerActivityTowerDefenseLevelApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.activity_tower_defense_level_apply_req) 9 | public class HandlerActivityTowerDefenseLevelApplyReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Encode and send 14 | return session.encodeMsg(NetMsgId.activity_tower_defense_level_apply_succeed_ack); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharPotentialDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "CharPotential.json") 9 | public class CharPotentialDef extends BaseDef { 10 | private int Id; 11 | 12 | private int[] MasterSpecificPotentialIds; 13 | private int[] AssistSpecificPotentialIds; 14 | private int[] CommonPotentialIds; 15 | private int[] MasterNormalPotentialIds; 16 | private int[] AssistNormalPotentialIds; 17 | 18 | @Override 19 | public int getId() { 20 | return Id; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/player/PlayerManager.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.player; 2 | 3 | public abstract class PlayerManager { 4 | private transient Player player; 5 | 6 | public PlayerManager() { 7 | 8 | } 9 | 10 | public PlayerManager(Player player) { 11 | this.player = player; 12 | } 13 | 14 | public Player getPlayer() { 15 | return this.player; 16 | } 17 | 18 | public void setPlayer(Player player) { 19 | if (this.player == null) { 20 | this.player = player; 21 | } 22 | } 23 | 24 | public int getPlayerUid() { 25 | return this.getPlayer().getUid(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/routes/HttpJsonResponse.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.routes; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import io.javalin.http.ContentType; 6 | import io.javalin.http.Context; 7 | import io.javalin.http.Handler; 8 | 9 | public class HttpJsonResponse implements Handler { 10 | private final String json; 11 | 12 | public HttpJsonResponse(String jsonString) { 13 | this.json = jsonString; 14 | } 15 | 16 | @Override 17 | public void handle(@NotNull Context ctx) throws Exception { 18 | ctx.status(200); 19 | ctx.contentType(ContentType.APPLICATION_JSON); 20 | ctx.result(json); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/MallMonthlyCardDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "MallMonthlyCard.json") 11 | public class MallMonthlyCardDef extends BaseDef { 12 | @SerializedName("Id") 13 | private String IdString; 14 | private int MonthlyCardId; 15 | private int Price; 16 | private int BaseItemId; 17 | private int BaseItemQty; 18 | 19 | @Override 20 | public int getId() { 21 | return IdString.hashCode(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ActivityDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "Activity.json") 10 | public class ActivityDef extends BaseDef { 11 | private int Id; 12 | private int ActivityType; 13 | 14 | private transient emu.nebula.game.activity.ActivityType type; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | 21 | @Override 22 | public void onLoad() { 23 | this.type = emu.nebula.game.activity.ActivityType.getByValue(this.ActivityType); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/StarTowerPotentialInfo.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower; 2 | 3 | import emu.nebula.proto.PublicStarTower.PotentialInfo; 4 | import lombok.Getter; 5 | 6 | @Getter 7 | public class StarTowerPotentialInfo { 8 | private int id; 9 | private int level; 10 | 11 | public StarTowerPotentialInfo(int id, int level) { 12 | this.id = id; 13 | this.level = level; 14 | } 15 | 16 | // Proto 17 | 18 | public PotentialInfo toProto() { 19 | var proto = PotentialInfo.newInstance() 20 | .setTid(this.getId()) 21 | .setLevel(this.getLevel()); 22 | 23 | return proto; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/FateCardDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.AccessLevel; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | @Getter 10 | @ResourceType(name = "FateCard.json") 11 | public class FateCardDef extends BaseDef { 12 | private int Id; 13 | 14 | private boolean IsTower; 15 | private boolean IsVampire; 16 | private boolean IsVampireSpecial; 17 | private boolean Removable; 18 | 19 | @Setter(AccessLevel.PROTECTED) 20 | private transient int bundleId; 21 | 22 | @Override 23 | public int getId() { 24 | return Id; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerAchievementInfoReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.achievement_info_req) 9 | public class HandlerAchievementInfoReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Build response 14 | var rsp = session.getPlayer().getAchievementManager().toProto(); 15 | 16 | // Encode and send 17 | return session.encodeMsg(NetMsgId.achievement_info_succeed_ack, rsp); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerVampireTalentResetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.vampire_talent_reset_req) 9 | public class HandlerVampireTalentResetReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Reset talents 14 | session.getPlayer().getVampireSurvivorManager().resetTalents(); 15 | 16 | // Encode and send 17 | return session.encodeMsg(NetMsgId.vampire_talent_reset_succeed_ack); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/SubNoteSkillPromoteGroupDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "SubNoteSkillPromoteGroup.json") 10 | public class SubNoteSkillPromoteGroupDef extends BaseDef { 11 | private int Id; 12 | private String SubNoteSkills; 13 | 14 | private transient ItemParamMap items; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | 21 | @Override 22 | public void onLoad() { 23 | this.items = ItemParamMap.fromJsonString(this.SubNoteSkills); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerBattlePassInfoReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.battle_pass_info_req) 9 | public class HandlerBattlePassInfoReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Get battle pass proto 14 | var info = session.getPlayer().getBattlePassManager().getBattlePass().toProto(); 15 | 16 | // Encode and send 17 | return session.encodeMsg(NetMsgId.battle_pass_info_succeed_ack, info); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/quest/QuestType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.quest; 2 | 3 | public class QuestType { 4 | public static final int UnknownQuest = 0; 5 | public static final int TourGuide = 1; 6 | public static final int Daily = 2; 7 | public static final int TravelerDuel = 3; 8 | public static final int TravelerDuelChallenge = 4; 9 | public static final int Affinity = 5; 10 | public static final int BattlePassDaily = 6; 11 | public static final int BattlePassWeekly = 7; 12 | public static final int VampireSurvivorNormal = 8; 13 | public static final int VampireSurvivorSeason = 9; 14 | public static final int Tower = 10; 15 | public static final int Demon = 11; 16 | public static final int TowerEvent = 12; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerPingReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerPing.Pong; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.Nebula; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.player_ping_req) 11 | public class HandlerPlayerPingReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Create response 16 | var rsp = Pong.newInstance() 17 | .setServerTs(Nebula.getCurrentTime()); 18 | 19 | return session.encodeMsg(NetMsgId.player_ping_succeed_ack, rsp); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaNewbieObtainReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.GachaNewbieObtain.GachaNewbieObtainReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.gacha_newbie_obtain_req) 10 | public class HandlerGachaNewbieObtainReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | @SuppressWarnings("unused") 15 | var req = GachaNewbieObtainReq.parseFrom(message); 16 | 17 | // TODO 18 | return session.encodeMsg(NetMsgId.gacha_newbie_obtain_failed_ack); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/GachaStorageDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.data.ResourceType.LoadPriority; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "GachaStorage.json", loadPriority = LoadPriority.HIGH) 10 | public class GachaStorageDef extends BaseDef { 11 | private int Id; 12 | 13 | private int DefaultId; 14 | private int DefaultQty; 15 | private int CostId; 16 | private int CostQty; 17 | 18 | private int ATypeUpProb; 19 | private int BTypeProb; 20 | private int BTypeUpProb; 21 | private int BTypeGuaranteeProb; 22 | 23 | @Override 24 | public int getId() { 25 | return Id; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TalentGroupDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import java.util.Set; 4 | import java.util.TreeSet; 5 | 6 | import emu.nebula.data.BaseDef; 7 | import emu.nebula.data.ResourceType; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | @Getter 12 | @ResourceType(name = "TalentGroup.json") 13 | public class TalentGroupDef extends BaseDef { 14 | private int Id; 15 | private int CharId; 16 | private int PreGroup; 17 | 18 | @Setter 19 | private transient TalentDef mainTalent; 20 | private transient Set talents; 21 | 22 | public TalentGroupDef() { 23 | this.talents = new TreeSet<>(); 24 | } 25 | 26 | @Override 27 | public int getId() { 28 | return Id; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerLearnReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.NewbieInfo; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_learn_req) 10 | public class HandlerPlayerLearnReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var req = NewbieInfo.parseFrom(message); 15 | 16 | // TODO set newbie info 17 | session.getPlayer().setNewbieInfo(req.getGroupId(), req.getStepId()); 18 | 19 | return session.encodeMsg(NetMsgId.player_learn_succeed_ack); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Nebula Nightly 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v4 15 | - name: Set up JDK 21 16 | uses: actions/setup-java@v4 17 | with: 18 | java-version: '21' 19 | distribution: 'temurin' 20 | 21 | - name: Setup Gradle 22 | uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 23 | 24 | - name: Build 25 | run: | 26 | chmod +x gradlew 27 | ./gradlew jar 28 | 29 | - name: Upload artifact 30 | uses: actions/upload-artifact@v4 31 | with: 32 | name: Nebula-Nightly 33 | path: Nebula.jar 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/room/StarTowerBattleRoom.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.room; 2 | 3 | import emu.nebula.data.resources.StarTowerStageDef; 4 | import emu.nebula.game.tower.StarTowerGame; 5 | import emu.nebula.game.tower.cases.StarTowerBattleCase; 6 | import emu.nebula.game.tower.cases.StarTowerSyncHPCase; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class StarTowerBattleRoom extends StarTowerBaseRoom { 11 | public StarTowerBattleRoom(StarTowerGame game, StarTowerStageDef stage) { 12 | super(game, stage); 13 | } 14 | 15 | @Override 16 | public void onEnter() { 17 | // Create battle case 18 | this.addCase(new StarTowerBattleCase()); 19 | 20 | // Create sync hp case 21 | this.addCase(new StarTowerSyncHPCase()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TitleDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "Title.json", loadPriority = LoadPriority.LOW) 11 | public class TitleDef extends BaseDef { 12 | private int Id; 13 | private int ItemId; 14 | private int TitleType; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | 21 | @Override 22 | public void onLoad() { 23 | var item = GameData.getItemDataTable().get(this.getItemId()); 24 | if (item != null) { 25 | item.setTitleData(this); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMailListReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.Mails; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.mail_list_req) 10 | public class HandlerMailListReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build mail list proto 15 | var rsp = Mails.newInstance(); 16 | 17 | for (var mail : session.getPlayer().getMailbox()) { 18 | rsp.addList(mail.toProto()); 19 | } 20 | 21 | return session.encodeMsg(NetMsgId.mail_list_succeed_ack, rsp); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ActivityShopDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 6 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "ActivityShop.json") 11 | public class ActivityShopDef extends BaseDef { 12 | private int Id; 13 | private int CurrencyItemId; 14 | private int ExchangeItemId; 15 | private double Rate; 16 | 17 | private Int2ObjectMap goods; 18 | 19 | @Override 20 | public int getId() { 21 | return Id; 22 | } 23 | 24 | @Override 25 | public void onLoad() { 26 | this.goods = new Int2ObjectOpenHashMap<>(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/room/StarTowerEventRoom.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.room; 2 | 3 | import emu.nebula.data.resources.StarTowerStageDef; 4 | import emu.nebula.game.tower.StarTowerGame; 5 | import emu.nebula.game.tower.cases.StarTowerSyncHPCase; 6 | 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class StarTowerEventRoom extends StarTowerBaseRoom { 11 | 12 | public StarTowerEventRoom(StarTowerGame game, StarTowerStageDef stage) { 13 | super(game, stage); 14 | } 15 | 16 | @Override 17 | public void onEnter() { 18 | // Create npc 19 | this.addCase(this.createNpcEvent()); 20 | 21 | // Create sync hp case 22 | this.addCase(new StarTowerSyncHPCase()); 23 | 24 | // Create door case 25 | this.createExit(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendListGetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.friend_list_get_req) 9 | public class HandlerFriendListGetReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Get cached friends list proto 14 | var proto = session.getPlayer().getFriendList().toProto(); 15 | 16 | // Clone response from cached proto 17 | var rsp = proto.clone(); 18 | 19 | // Encode and send 20 | return session.encodeMsg(NetMsgId.friend_list_get_succeed_ack, rsp); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/Snowflake.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util; 2 | 3 | public class Snowflake { 4 | private static final long EPOCH = 1735689600000L; // Wednesday, January 1, 2025 12:00:00 AM (GMT) 5 | private static int cachedTimestamp; 6 | private static byte sequence; 7 | 8 | public synchronized static int newUid() { 9 | int timestamp = (int) ((System.currentTimeMillis() - EPOCH) / 1000); 10 | 11 | if (cachedTimestamp != timestamp) { 12 | sequence = 0; 13 | cachedTimestamp = timestamp; 14 | } else { 15 | sequence++; 16 | } 17 | 18 | return (cachedTimestamp << 4) + sequence; 19 | } 20 | 21 | public synchronized static int toTimestamp(int snowflake) { 22 | return (snowflake >> 4) + (int) (EPOCH / 1000); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerClientEventReportReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.Nil; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.game.quest.QuestCondition; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.client_event_report_req) 11 | public class HandlerClientEventReportReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Interact 16 | session.getPlayer().trigger(QuestCondition.ClientReport, 1, 1005); 17 | 18 | // Encode response 19 | return session.encodeMsg(NetMsgId.client_event_report_succeed_ack, Nil.newInstance()); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/UseMode.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum UseMode { 8 | UseModeManual (1), 9 | UseModeAuto (2), 10 | UseModeNot (3); 11 | 12 | @Getter 13 | private final int value; 14 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 15 | 16 | static { 17 | for (UseMode type : UseMode.values()) { 18 | map.put(type.getValue(), type); 19 | } 20 | } 21 | 22 | private UseMode(int value) { 23 | this.value = value; 24 | } 25 | 26 | public static UseMode getByValue(int value) { 27 | return map.get(value); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerNameEditReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerNameEdit.PlayerNameEditReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_name_edit_req) 10 | public class HandlerPlayerNameEditReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var req = PlayerNameEditReq.parseFrom(message); 15 | 16 | boolean success = session.getPlayer().editName(req.getName()); 17 | 18 | return session.encodeMsg(success ? NetMsgId.player_name_edit_succeed_ack : NetMsgId.player_name_edit_failed_ack); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/PlotDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "Plot.json") 10 | public class PlotDef extends BaseDef { 11 | private int Id; 12 | private int Char; 13 | private int UnlockAffinityLevel; 14 | private String Rewards; 15 | 16 | private transient ItemParamMap rewards; 17 | 18 | @Override 19 | public int getId() { 20 | return this.Id; 21 | } 22 | 23 | public ItemParamMap getRewards() { 24 | return this.rewards; 25 | } 26 | 27 | @Override 28 | public void onLoad() { 29 | this.rewards = ItemParamMap.fromJsonString(this.Rewards); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStoryApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StoryApply.StoryApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.story_apply_req) 10 | public class HandlerStoryApplyReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = StoryApplyReq.parseFrom(message); 16 | 17 | // Apply for story 18 | session.getPlayer().getStoryManager().apply(req.getIdx()); 19 | 20 | // Encode response 21 | return session.encodeMsg(NetMsgId.story_apply_succeed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/WorldClassDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "WorldClass.json") 10 | public class WorldClassDef extends BaseDef { 11 | private int Id; 12 | private int Exp; 13 | private String Reward; 14 | 15 | private transient ItemParamMap rewards; 16 | 17 | @Override 18 | public int getId() { 19 | return Id; 20 | } 21 | 22 | @Override 23 | public void onLoad() { 24 | if (this.Reward != null) { 25 | this.rewards = ItemParamMap.fromJsonString(this.Reward); 26 | } else { 27 | this.rewards = new ItemParamMap(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/command/commands/ReloadCommand.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.command.commands; 2 | 3 | import emu.nebula.Nebula; 4 | import emu.nebula.command.Command; 5 | import emu.nebula.command.CommandArgs; 6 | import emu.nebula.command.CommandHandler; 7 | 8 | @Command(label = "reload", permission = "admin.reload", desc = "!reload = Reloads the server config.") 9 | public class ReloadCommand implements CommandHandler { 10 | 11 | @Override 12 | public String execute(CommandArgs args) { 13 | // Reload config first 14 | Nebula.loadConfig(); 15 | 16 | // Reload patch list if the server is running 17 | if (Nebula.getHttpServer() != null) { 18 | Nebula.getHttpServer().loadPatchList(); 19 | } 20 | 21 | // Result message 22 | return "Reloaded the server config"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/story/StoryChoiceInfo.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.story; 2 | 3 | import dev.morphia.annotations.Entity; 4 | import emu.nebula.proto.Public.StoryChoice; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @Entity(useDiscriminator = false) 9 | public class StoryChoiceInfo { 10 | private int group; 11 | private int value; 12 | 13 | @Deprecated 14 | public StoryChoiceInfo() { 15 | // Morphia only 16 | } 17 | 18 | public StoryChoiceInfo(int group, int value) { 19 | this.group = group; 20 | this.value = value; 21 | } 22 | 23 | // Proto 24 | 25 | public StoryChoice toProto() { 26 | var proto = StoryChoice.newInstance() 27 | .setGroup(this.getGroup()) 28 | .setValue(this.getValue()); 29 | 30 | return proto; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DictionaryEntryDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "DictionaryEntry.json", loadPriority = LoadPriority.LOW) 11 | public class DictionaryEntryDef extends BaseDef { 12 | private int Id; 13 | private int Tab; 14 | private int Index; 15 | 16 | @Override 17 | public int getId() { 18 | return Id; 19 | } 20 | 21 | @Override 22 | public void onLoad() { 23 | var dictionary = GameData.getDictionaryTabDataTable().get(this.getTab()); 24 | if (dictionary != null) { 25 | dictionary.getEntries().add(this); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/UseAction.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum UseAction { 8 | Drop (1), 9 | Item (2), 10 | Pick (3), 11 | No (4); 12 | 13 | @Getter 14 | private final int value; 15 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 16 | 17 | static { 18 | for (UseAction type : UseAction.values()) { 19 | map.put(type.getValue(), type); 20 | } 21 | } 22 | 23 | private UseAction(int value) { 24 | this.value = value; 25 | } 26 | 27 | public static UseAction getByValue(int value) { 28 | return map.get(value); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerFormationReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerFormation.PlayerFormationReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_formation_req) 10 | public class HandlerPlayerFormationReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var req = PlayerFormationReq.parseFrom(message); 15 | 16 | boolean success = session.getPlayer().getFormations().updateFormation(req.getFormation()); 17 | 18 | return session.encodeMsg(success ? NetMsgId.player_formation_succeed_ack : NetMsgId.player_formation_failed_ack); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerTowerGrowthDetailReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.TowerGrowthDetail.TowerGrowthDetailResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.tower_growth_detail_req) 10 | public class HandlerTowerGrowthDetailReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = TowerGrowthDetailResp.newInstance() 16 | .addAllDetail(session.getPlayer().getProgress().getStarTowerGrowth()); 17 | 18 | // Encode and send 19 | return session.encodeMsg(NetMsgId.tower_growth_detail_succeed_ack, rsp); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerBookFateCardBundleDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import java.util.List; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import it.unimi.dsi.fastutil.objects.ObjectArrayList; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "StarTowerBookFateCardBundle.json") 12 | public class StarTowerBookFateCardBundleDef extends BaseDef { 13 | private int Id; 14 | private int BundleId; 15 | 16 | private transient List cards; 17 | 18 | public StarTowerBookFateCardBundleDef() { 19 | this.cards = new ObjectArrayList<>(); 20 | } 21 | 22 | @Override 23 | public int getId() { 24 | return Id; 25 | } 26 | 27 | protected void addCard(FateCardDef card) { 28 | this.getCards().add(card); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendStarSetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendStarSet.FriendStarSetReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.friend_star_set_req) 10 | public class HandlerFriendStarSetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = FriendStarSetReq.parseFrom(message); 16 | 17 | // Set star 18 | session.getPlayer().getFriendList().setStar(req.getUIds(), req.getStar()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(NetMsgId.friend_star_set_succeed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DatingBranchDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.data.ResourceType.LoadPriority; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "DatingBranch.json", loadPriority = LoadPriority.LOW) 10 | public class DatingBranchDef extends BaseDef { 11 | private int Id; 12 | private int DatingEventType; 13 | private int[] DatingEventParams; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | 20 | public int getLandmarkId() { 21 | if (this.DatingEventParams.length <= 0) { 22 | return 0; 23 | } 24 | 25 | return this.DatingEventParams[0]; 26 | } 27 | 28 | @Override 29 | public void onLoad() { 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/VampireSurvivorDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @ResourceType(name = "VampireSurvivor.json") 9 | public class VampireSurvivorDef extends BaseDef { 10 | private int Id; 11 | private int Mode; 12 | private int NeedWorldClass; 13 | private int[] FateCardBundle; 14 | 15 | private int NormalScore1; 16 | private int EliteScore1; 17 | private int BossScore1; 18 | private int TimeScore1; 19 | private int TimeLimit1; 20 | 21 | private int NormalScore2; 22 | private int EliteScore2; 23 | private int BossScore2; 24 | private int TimeScore2; 25 | private int TimeLimit2; 26 | 27 | @Override 28 | public int getId() { 29 | return Id; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/cases/StarTowerSyncHPCase.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.cases; 2 | 3 | import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; 4 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; 5 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class StarTowerSyncHPCase extends StarTowerBaseCase { 10 | 11 | @Override 12 | public CaseType getType() { 13 | return CaseType.SyncHP; 14 | } 15 | 16 | @Override 17 | public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { 18 | return rsp; 19 | } 20 | 21 | // Proto 22 | 23 | @Override 24 | public void encodeProto(StarTowerRoomCase proto) { 25 | // Set field in the proto 26 | proto.getMutableSyncHPCase(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerBoardSetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerBoard.PlayerBoardSetReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_board_set_req) 10 | public class HandlerPlayerBoardSetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = PlayerBoardSetReq.parseFrom(message); 16 | 17 | // Set board 18 | boolean success = session.getPlayer().setBoard(req.getIds()); 19 | 20 | return session.encodeMsg(success ? NetMsgId.player_board_set_succeed_ack : NetMsgId.player_board_set_failed_ack); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerDataReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.player_data_req) 9 | public class HandlerPlayerDataReq extends NetHandler { 10 | 11 | public boolean requirePlayer() { 12 | return false; 13 | } 14 | 15 | @Override 16 | public byte[] handle(GameSession session, byte[] message) throws Exception { 17 | // Check if player has been created yet 18 | if (session.getPlayer() == null) { 19 | return session.encodeMsg(NetMsgId.player_new_notify); 20 | } 21 | 22 | // Encode player data 23 | return session.encodeMsg(NetMsgId.player_data_succeed_ack, session.getPlayer().toProto()); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerStageDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import emu.nebula.game.tower.room.RoomType; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "StarTowerStage.json") 12 | public class StarTowerStageDef extends BaseDef { 13 | private int Id; 14 | private int Stage; 15 | private int Floor; 16 | private int InteriorCurrencyQuantity; 17 | @SerializedName("RoomType") 18 | private int RoomTypeValue; 19 | 20 | private transient RoomType roomType; 21 | 22 | @Override 23 | public int getId() { 24 | return Id; 25 | } 26 | 27 | @Override 28 | public void onLoad() { 29 | this.roomType = RoomType.getByValue(this.RoomTypeValue); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/error/ServerException.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.error; 2 | 3 | import lombok.Getter; 4 | import emu.nebula.proto.Public.Error; 5 | 6 | @Getter 7 | public class ServerException extends Exception { 8 | private static final long serialVersionUID = -8953641375717705518L; 9 | private int code; 10 | private String[] args; 11 | 12 | public ServerException(int code) { 13 | this.code = code; 14 | } 15 | 16 | public ServerException(int code, String... args) { 17 | this.code = code; 18 | this.args = args; 19 | } 20 | 21 | // Proto 22 | 23 | public Error toProto() { 24 | var proto = Error.newInstance() 25 | .setCode(code); 26 | 27 | if (this.args != null) { 28 | proto.addAllArguments(args); 29 | } 30 | 31 | return proto; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/ItemParam.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import dev.morphia.annotations.Entity; 6 | import emu.nebula.proto.Public.ItemTpl; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @Entity(useDiscriminator = false) 11 | public class ItemParam { 12 | @SerializedName("Tid") 13 | public int id; 14 | 15 | @SerializedName("Qty") 16 | public int count; 17 | 18 | @Deprecated // Morphia only 19 | public ItemParam() { 20 | 21 | } 22 | 23 | public ItemParam(int id, int count) { 24 | this.id = id; 25 | this.count = count; 26 | } 27 | 28 | public ItemTpl toProto() { 29 | var proto = ItemTpl.newInstance() 30 | .setTid(this.getId()) 31 | .setQty(this.getCount()); 32 | 33 | return proto; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerDailyShopRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.net.HandlerId; 6 | import emu.nebula.net.GameSession; 7 | 8 | @HandlerId(NetMsgId.daily_shop_reward_receive_req) 9 | public class HandlerDailyShopRewardReceiveReq extends NetHandler { 10 | 11 | @Override 12 | public byte[] handle(GameSession session, byte[] message) throws Exception { 13 | // Claim daily reward 14 | var change = session.getPlayer().getQuestManager().claimDailyReward(); 15 | 16 | if (change == null) { 17 | return session.encodeMsg(NetMsgId.daily_shop_reward_receive_failed_ack); 18 | } 19 | 20 | // Encode and send 21 | return session.encodeMsg(NetMsgId.daily_shop_reward_receive_succeed_ack, change.toProto()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendDeleteReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendDelete.FriendDeleteReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.friend_delete_req) 10 | public class HandlerFriendDeleteReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = FriendDeleteReq.parseFrom(message); 16 | 17 | // Delete friend 18 | boolean success = session.getPlayer().getFriendList().deleteFriend((int) req.getUId()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(success ? NetMsgId.friend_delete_succeed_ack : NetMsgId.friend_delete_failed_ack); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerCharsShowReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerCharsShow.PlayerCharsShowReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_chars_show_req) 10 | public class HandlerPlayerCharsShowReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse req 15 | var req = PlayerCharsShowReq.parseFrom(message); 16 | 17 | // Set 18 | boolean success = session.getPlayer().setShowChars(req.getCharIds()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(success ? NetMsgId.player_chars_show_succeed_ack : NetMsgId.player_chars_show_failed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/instance/InstanceSettleData.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.instance; 2 | 3 | import emu.nebula.game.inventory.ItemParamMap; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | 7 | @Getter @Setter 8 | public class InstanceSettleData { 9 | private boolean isWin; 10 | private boolean isFirst; 11 | private int exp; 12 | 13 | private ItemParamMap firstRewards; 14 | private ItemParamMap rewards; 15 | 16 | public InstanceSettleData() { 17 | 18 | } 19 | 20 | public void generateRewards(InstanceData data) { 21 | this.generateRewards(data, 0); 22 | } 23 | 24 | public void generateRewards(InstanceData data, int rewardType) { 25 | if (this.isFirst) { 26 | this.firstRewards = data.getFirstRewards(rewardType).generate(); 27 | } 28 | 29 | this.rewards = data.getRewards(rewardType).generate(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerActivityDetailReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.ActivityDetail.ActivityResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.activity_detail_req) 10 | public class HandlerActivityDetailReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = ActivityResp.newInstance(); 16 | 17 | for (var activity : session.getPlayer().getActivityManager().getActivities().values()) { 18 | rsp.addList(activity.toMsgProto()); 19 | } 20 | 21 | // Encode and send 22 | return session.encodeMsg(NetMsgId.activity_detail_succeed_ack, rsp); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerTitleEditReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerTitleEdit.PlayerTitleEditReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_title_edit_req) 10 | public class HandlerPlayerTitleEditReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = PlayerTitleEditReq.parseFrom(message); 16 | 17 | boolean success = session.getPlayer().editTitle(req.getTitlePrefix(), req.getTitleSuffix()); 18 | 19 | // Send response 20 | return session.encodeMsg(success ? NetMsgId.player_title_edit_succeed_ack : NetMsgId.player_title_edit_failed_ack); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/WeightedList.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util; 2 | 3 | import java.util.NavigableMap; 4 | import java.util.TreeMap; 5 | import java.util.concurrent.ThreadLocalRandom; 6 | 7 | public class WeightedList { 8 | private final NavigableMap map = new TreeMap<>(); 9 | private double total = 0; 10 | 11 | public WeightedList() { 12 | 13 | } 14 | 15 | public WeightedList add(double weight, E result) { 16 | if (weight <= 0) return this; 17 | total += weight; 18 | map.put(total, result); 19 | return this; 20 | } 21 | 22 | public E next() { 23 | double value = ThreadLocalRandom.current().nextDouble() * total; 24 | return map.higherEntry(value).getValue(); 25 | } 26 | 27 | public int size() { 28 | return map.size(); 29 | } 30 | 31 | public void clear() { 32 | this.map.clear(); 33 | this.total = 0; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendAddReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendAdd.FriendAddReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.friend_add_req) 10 | public class HandlerFriendAddReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = FriendAddReq.parseFrom(message); 16 | int uid = (int) req.getUId(); 17 | 18 | // Send friend request 19 | boolean success = session.getPlayer().getFriendList().sendFriendRequest(uid); 20 | 21 | // Encode and send 22 | return session.encodeMsg(success ? NetMsgId.friend_add_succeed_ack : NetMsgId.friend_add_failed_ack); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/MallPackageDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import emu.nebula.game.inventory.ItemParamMap; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "MallPackage.json") 12 | public class MallPackageDef extends BaseDef { 13 | @SerializedName("Id") 14 | private String IdString; 15 | private int Stock; 16 | private int CurrencyType; 17 | private int CurrencyItemId; 18 | private int CurrencyItemQty; 19 | private String Items; 20 | 21 | private transient ItemParamMap products; 22 | 23 | @Override 24 | public int getId() { 25 | return IdString.hashCode(); 26 | } 27 | 28 | @Override 29 | public void onLoad() { 30 | this.products = ItemParamMap.fromJsonString(this.Items); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/battlepass/BattlePassManager.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.battlepass; 2 | 3 | import emu.nebula.Nebula; 4 | import emu.nebula.game.player.Player; 5 | import emu.nebula.game.player.PlayerManager; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class BattlePassManager extends PlayerManager { 10 | private BattlePass battlePass; 11 | 12 | public BattlePassManager(Player player) { 13 | super(player); 14 | } 15 | 16 | public boolean hasNew() { 17 | return this.getBattlePass().hasNew(); 18 | } 19 | 20 | // Database 21 | 22 | public void loadFromDatabase() { 23 | this.battlePass = Nebula.getGameDatabase().getObjectByUid(BattlePass.class, getPlayer().getUid()); 24 | 25 | if (this.battlePass == null) { 26 | this.battlePass = new BattlePass(this); 27 | } else { 28 | this.battlePass.setManager(this); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaInformationReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.GachaInformation.GachaInformationResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.gacha_information_req) 10 | public class HandlerGachaInformationReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = GachaInformationResp.newInstance(); 16 | 17 | for (var bannerInfo : session.getPlayer().getGachaManager().getBannerInfos()) { 18 | rsp.addInformation(bannerInfo.toProto()); 19 | } 20 | 21 | // Encode and send 22 | return session.encodeMsg(NetMsgId.gacha_information_succeed_ack, rsp); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerVampireTalentUnlockReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.vampire_talent_unlock_req) 10 | public class HandlerVampireTalentUnlockReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = UI32.parseFrom(message); 16 | 17 | // Unlock talent 18 | boolean success = session.getPlayer().getVampireSurvivorManager().unlockTalent(req.getValue()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(success ? NetMsgId.vampire_talent_unlock_succeed_ack : NetMsgId.vampire_talent_unlock_failed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerHeadIconSetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerHeadiconSet.PlayerHeadIconSetReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_head_icon_set_req) 10 | public class HandlerPlayerHeadIconSetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse req 15 | var req = PlayerHeadIconSetReq.parseFrom(message); 16 | 17 | // Set head icon 18 | boolean result = session.getPlayer().editHeadIcon(req.getHeadIcon()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(result ? NetMsgId.player_head_icon_set_succeed_ack : NetMsgId.player_head_icon_set_failed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerScoreBossApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.ScoreBossApply.ScoreBossApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.score_boss_apply_req) 10 | public class HandlerScoreBossApplyReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = ScoreBossApplyReq.parseFrom(message); 16 | 17 | // Apply 18 | boolean success = session.getPlayer().getScoreBossManager().apply(req.getLevelId(), req.getBuildId()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(success ? NetMsgId.score_boss_apply_succeed_ack : NetMsgId.score_boss_apply_failed_ack); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TowerDefenseLevelDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "TowerDefenseLevel.json") 10 | public class TowerDefenseLevelDef extends BaseDef { 11 | private int Id; 12 | private int Condition2; 13 | private int Condition3; 14 | private int Item1; 15 | private int Qty1; 16 | private int Item2; 17 | private int Qty2; 18 | 19 | private transient ItemParamMap rewards; 20 | 21 | @Override 22 | public int getId() { 23 | return Id; 24 | } 25 | 26 | @Override 27 | public void onLoad() { 28 | // Parse rewards 29 | this.rewards = new ItemParamMap(); 30 | this.rewards.add(this.Item1, this.Qty1); 31 | this.rewards.add(this.Item2, this.Qty2); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/dating/DatingGame.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.dating; 2 | 3 | import emu.nebula.data.resources.DatingLandmarkDef; 4 | import emu.nebula.game.character.GameCharacter; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class DatingGame { 9 | private GameCharacter character; 10 | private DatingLandmarkDef landmark; 11 | 12 | private int[] branchOptionsA; 13 | private int[] branchOptionsB; 14 | 15 | public DatingGame(GameCharacter character, DatingLandmarkDef landmark) { 16 | this.character = character; 17 | this.landmark = landmark; 18 | this.branchOptionsA = new int[] {1, 2}; 19 | this.branchOptionsB = new int[] {1, 2}; 20 | } 21 | 22 | public boolean selectDatingBranchA(int optionId) { 23 | // TODO 24 | return true; 25 | } 26 | 27 | public boolean selectDatingBranchB(int optionId) { 28 | // TODO 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tutorial/TutorialLevelLog.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tutorial; 2 | 3 | import dev.morphia.annotations.Entity; 4 | import emu.nebula.proto.Public.TutorialLevel; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | @Entity(useDiscriminator = false) 9 | public class TutorialLevelLog { 10 | private int id; 11 | private boolean claimed; 12 | 13 | @Deprecated // Morphia only 14 | public TutorialLevelLog() { 15 | 16 | } 17 | 18 | public TutorialLevelLog(int id) { 19 | this.id = id; 20 | } 21 | 22 | public void setClaimed(boolean value) { 23 | this.claimed = value; 24 | } 25 | 26 | // Proto 27 | 28 | public TutorialLevel toProto() { 29 | var proto = TutorialLevel.newInstance() 30 | .setLevelId(this.getId()) 31 | .setPassed(true) 32 | .setRewardReceived(this.isClaimed()); 33 | 34 | return proto; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaNewbieInfoReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.GachaNewbieInfoOuterClass.GachaNewbieInfo; 6 | import emu.nebula.proto.GachaNewbieInfoOuterClass.GachaNewbieInfoResp; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.gacha_newbie_info_req) 11 | public class HandlerGachaNewbieInfoReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | var rsp = GachaNewbieInfoResp.newInstance(); 16 | 17 | var info = GachaNewbieInfo.newInstance() 18 | .setId(5) 19 | .setReceive(true); 20 | 21 | rsp.addList(info); 22 | 23 | return session.encodeMsg(NetMsgId.gacha_newbie_info_succeed_ack, rsp); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPhoneContactsInfoReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PhoneContactsInfo.PhoneContactsInfoResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.phone_contacts_info_req) 10 | public class HandlerPhoneContactsInfoReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = PhoneContactsInfoResp.newInstance(); 16 | 17 | for (var character : session.getPlayer().getCharacters().getCharacterCollection()) { 18 | rsp.addList(character.getContact().toProto()); 19 | } 20 | 21 | // Encode and send 22 | return session.encodeMsg(NetMsgId.phone_contacts_info_succeed_ack, rsp); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStorySetRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StorySetRewardReceive.StorySetRewardReceiveReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.story_set_reward_receive_req) 10 | public class HandlerStorySetRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = StorySetRewardReceiveReq.parseFrom(message); 16 | 17 | // Settle 18 | var changes = session.getPlayer().getStoryManager().settleSet(req.getChapterId(), req.getSectionId()); 19 | 20 | // Finish 21 | return session.encodeMsg(NetMsgId.story_set_reward_receive_succeed_ack, changes.toProto()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerHeadIconInfoReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerHeadInfo.PlayerHeadIconInfoResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_head_icon_info_req) 10 | public class HandlerPlayerHeadIconInfoReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = PlayerHeadIconInfoResp.newInstance(); 16 | 17 | var icons = session.getPlayer().getInventory().getAllHeadIcons(); 18 | 19 | for (int id : icons) { 20 | rsp.addList(id); 21 | } 22 | 23 | // Encode and send 24 | return session.encodeMsg(NetMsgId.player_head_icon_info_succeed_ack, rsp); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/custom/AchievementParamDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.custom; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "AchievementParam.json", useInternal = true, loadPriority = LoadPriority.LOW) 11 | public class AchievementParamDef extends BaseDef { 12 | private int Id; 13 | 14 | private int Param1; 15 | private int ParamCond1; 16 | private int Param2; 17 | private int ParamCond2; 18 | 19 | @Override 20 | public int getId() { 21 | return Id; 22 | } 23 | 24 | @Override 25 | public void onLoad() { 26 | var achievement = GameData.getAchievementDataTable().get(this.Id); 27 | if (achievement == null) { 28 | return; 29 | } 30 | 31 | achievement.setParams(this); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMailReadReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.MailRequest; 6 | import emu.nebula.proto.Public.UI32; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.mail_read_req) 11 | public class HandlerMailReadReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | var req = MailRequest.parseFrom(message); 16 | 17 | boolean result = session.getPlayer().getMailbox().readMail(req.getId(), req.getFlag()); 18 | 19 | if (!result) { 20 | return session.encodeMsg(NetMsgId.mail_read_failed_ack); 21 | } 22 | 23 | return session.encodeMsg(NetMsgId.mail_read_succeed_ack, UI32.newInstance().setValue(req.getId())); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ProductionDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "Production.json") 11 | public class ProductionDef extends BaseDef { 12 | private int Id; 13 | private int UnlockWorldLevel; 14 | private int ProductionId; 15 | private int ProductionPerBatch; 16 | private int RawMaterialId1; 17 | private int RawMaterialCount1; 18 | 19 | private transient ItemParamMap materials; 20 | 21 | @Override 22 | public int getId() { 23 | return Id; 24 | } 25 | 26 | @Override 27 | public void onLoad() { 28 | this.materials = new ItemParamMap(); 29 | 30 | if (this.RawMaterialId1 > 0) { 31 | this.materials.add(this.RawMaterialId1, this.RawMaterialCount1); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerEventDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import it.unimi.dsi.fastutil.ints.IntArrayList; 6 | import it.unimi.dsi.fastutil.ints.IntList; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "StarTowerEvent.json") 11 | public class StarTowerEventDef extends BaseDef { 12 | private int Id; 13 | private int[] RelatedNPCs; 14 | 15 | private transient IntList optionIds; 16 | 17 | @Override 18 | public int getId() { 19 | return Id; 20 | } 21 | 22 | /** 23 | * Returns a deep copy of our option ids 24 | */ 25 | public IntList getClonedOptionIds() { 26 | var list = new IntArrayList(); 27 | list.addAll(this.getOptionIds()); 28 | return list; 29 | } 30 | 31 | @Override 32 | public void onLoad() { 33 | this.optionIds = new IntArrayList(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGemConvertReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.gem_convert_req) 10 | public class HandlerGemConvertReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = UI32.parseFrom(message); 16 | 17 | // Convert gems 18 | var change = session.getPlayer().getInventory().convertGems(req.getValue()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.gem_convert_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.gem_convert_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendInvitesDeleteReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendInvitesDelete.FriendInvitesDeleteReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.friend_invites_delete_req) 10 | public class HandlerFriendInvitesDeleteReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = FriendInvitesDeleteReq.parseFrom(message); 16 | 17 | // Delete all invites 18 | for (long uid : req.getMutableUIds()) { 19 | session.getPlayer().getFriendList().handleFriendRequest((int) uid, false); 20 | } 21 | 22 | // Encode and send 23 | return session.encodeMsg(NetMsgId.friend_invites_delete_succeed_ack); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerScoreBossStarRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.ScoreBossStarRewardReceive.ScoreBossStarRewardReceiveReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.score_boss_star_reward_receive_req) 10 | public class HandlerScoreBossStarRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = ScoreBossStarRewardReceiveReq.parseFrom(message); 16 | 17 | // Claim rewards 18 | var change = session.getPlayer().getScoreBossManager().claimRewards(req.getStar()); 19 | 20 | // Encode and send 21 | return session.encodeMsg(NetMsgId.score_boss_star_reward_receive_succeed_ack, change.toProto()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StoryDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParam; 6 | import emu.nebula.game.inventory.ItemParamMap; 7 | import emu.nebula.util.JsonUtils; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "Story.json") 12 | public class StoryDef extends BaseDef { 13 | private int Id; 14 | private int Chapter; 15 | private String RewardDisplay; 16 | 17 | private transient ItemParamMap rewards; 18 | 19 | @Override 20 | public int getId() { 21 | return Id; 22 | } 23 | 24 | @Override 25 | public void onLoad() { 26 | var list = JsonUtils.decodeList(this.getRewardDisplay(), ItemParam.class); 27 | 28 | if (list != null) { 29 | rewards = ItemParamMap.fromItemParams(list); 30 | } else { 31 | rewards = new ItemParamMap(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerSkinShowReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerSkinShow.PlayerSkinShowReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_skin_show_req) 10 | public class HandlerPlayerSkinShowReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse req 15 | var req = PlayerSkinShowReq.parseFrom(message); 16 | 17 | // Set player skin 18 | boolean success = session.getPlayer().setSkin(req.getSkinId()); 19 | 20 | if (success == false) { 21 | session.encodeMsg(NetMsgId.player_skin_show_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.player_skin_show_succeed_ack); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/room/RoomType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.room; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum RoomType { 8 | BattleRoom (0), 9 | EliteBattleRoom (1), 10 | BossRoom (2), 11 | FinalBossRoom (3), 12 | DangerRoom (4), 13 | HorrorRoom (5), 14 | ShopRoom (6), 15 | EventRoom (7), 16 | UnifyBattleRoom (15); 17 | 18 | @Getter 19 | private final int value; 20 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 21 | 22 | static { 23 | for (RoomType type : RoomType.values()) { 24 | map.put(type.getValue(), type); 25 | } 26 | } 27 | 28 | private RoomType(int value) { 29 | this.value = value; 30 | } 31 | 32 | public static RoomType getByValue(int value) { 33 | return map.get(value); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/ResourceType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface ResourceType { 8 | 9 | /** Names of the file that this Resource loads from */ 10 | String name(); 11 | 12 | /** 13 | * Load priority - dictates which order to load this resource, with "highest" being loaded first 14 | */ 15 | LoadPriority loadPriority() default LoadPriority.NORMAL; 16 | 17 | /** 18 | * Loads the resource file from inside the jar (./resources/defs/) if set to true 19 | */ 20 | boolean useInternal() default false; 21 | 22 | public enum LoadPriority { 23 | HIGHEST(4), HIGH(3), NORMAL(2), LOW(1), LOWEST(0); 24 | 25 | private final int value; 26 | 27 | LoadPriority(int value) { 28 | this.value = value; 29 | } 30 | 31 | public int value() { 32 | return value; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/EventOptionsDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | 8 | import lombok.Getter; 9 | 10 | /** 11 | * We don't need a DataTable for this, since we are only using this class to verify event options for the client 12 | */ 13 | @Getter 14 | @ResourceType(name = "EventOptions.json", loadPriority = LoadPriority.LOW) 15 | public class EventOptionsDef extends BaseDef { 16 | private int Id; 17 | 18 | @Override 19 | public int getId() { 20 | return Id; 21 | } 22 | 23 | @Override 24 | public void onLoad() { 25 | // Get event 26 | var event = GameData.getStarTowerEventDataTable().get(this.Id / 100); 27 | if (event == null) { 28 | return; 29 | } 30 | 31 | // Add to avaliable options 32 | event.getOptionIds().add(this.getId()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerItemProductReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.ItemProduct.ItemProductReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.item_product_req) 10 | public class HandlerItemProductReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = ItemProductReq.parseFrom(message); 16 | 17 | // Produce item 18 | var change = session.getPlayer().getInventory().produce(req.getId(), req.getNum(), null); 19 | 20 | if (change.isEmpty()) { 21 | return session.encodeMsg(NetMsgId.item_product_failed_ack); 22 | } 23 | 24 | // Send response 25 | return session.encodeMsg(NetMsgId.item_product_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ChatDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "Chat.json", loadPriority = LoadPriority.LOW) 11 | public class ChatDef extends BaseDef { 12 | private int Id; 13 | private int AddressBookId; 14 | private int PreChatId; 15 | 16 | private int TriggerType; 17 | private int TriggerCond; 18 | private String TriggerCondParam; 19 | 20 | private int Reward1; 21 | private int RewardQty1; 22 | 23 | @Override 24 | public int getId() { 25 | return Id; 26 | } 27 | 28 | @Override 29 | public void onLoad() { 30 | var character = GameData.getCharacterDataTable().get(this.AddressBookId); 31 | 32 | if (character != null) { 33 | character.getChats().add(this); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/dating/DatingEventType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.dating; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum DatingEventType { 8 | Start (1), 9 | End (2), 10 | Landmark (3), 11 | Regular (4), 12 | LimitedLandmark (5), 13 | BranchA (6), 14 | BranchB (7), 15 | BeforeBranch (8), 16 | AfterBranch (9); 17 | 18 | @Getter 19 | private final int value; 20 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 21 | 22 | static { 23 | for (DatingEventType type : DatingEventType.values()) { 24 | map.put(type.getValue(), type); 25 | } 26 | } 27 | 28 | private DatingEventType(int value) { 29 | this.value = value; 30 | } 31 | 32 | public static DatingEventType getByValue(int value) { 33 | return map.get(value); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/agent/AgentResult.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.agent; 2 | 3 | import emu.nebula.game.inventory.ItemParamMap; 4 | 5 | public class AgentResult { 6 | private Agent agent; 7 | private ItemParamMap rewards; 8 | private ItemParamMap bonus; 9 | 10 | public AgentResult(Agent agent) { 11 | this.agent = agent; 12 | } 13 | 14 | public Agent getAgent() { 15 | return this.agent; 16 | } 17 | 18 | public ItemParamMap getRewards() { 19 | if (this.rewards == null) { 20 | return ItemParamMap.EMPTY; 21 | } 22 | 23 | return this.rewards; 24 | } 25 | 26 | public ItemParamMap getBonus() { 27 | if (this.bonus == null) { 28 | return ItemParamMap.EMPTY; 29 | } 30 | 31 | return this.bonus; 32 | } 33 | 34 | public void setRewards(ItemParamMap rewards) { 35 | this.rewards = rewards; 36 | } 37 | 38 | public void setBonus(ItemParamMap bonus) { 39 | this.bonus = bonus; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStorySettleReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StorySett.StorySettleReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.story_settle_req) 10 | public class HandlerStorySettleReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = StorySettleReq.parseFrom(message); 16 | 17 | // Settle 18 | var change = session.getPlayer().getStoryManager().settle(req.getList(), req.getEvidences()); 19 | 20 | // Handle client events for achievements 21 | session.getPlayer().getAchievementManager().handleClientEvents(req.getEvents()); 22 | 23 | // Send response 24 | return session.encodeMsg(NetMsgId.story_settle_succeed_ack, change.toProto()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMallGemListReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MallGemListOuterClass.GemInfo; 6 | import emu.nebula.proto.MallGemListOuterClass.MallGemList; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.data.GameData; 9 | import emu.nebula.net.GameSession; 10 | 11 | @HandlerId(NetMsgId.mall_gem_list_req) 12 | public class HandlerMallGemListReq extends NetHandler { 13 | 14 | @Override 15 | public byte[] handle(GameSession session, byte[] message) throws Exception { 16 | var rsp = MallGemList.newInstance(); 17 | 18 | for (var data : GameData.getMallGemDataTable()) { 19 | var info = GemInfo.newInstance() 20 | .setId(data.getIdString()) 21 | .setMaiden(true); 22 | 23 | rsp.addList(info); 24 | } 25 | 26 | return session.encodeMsg(NetMsgId.mall_gem_list_succeed_ack, rsp); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerQuestDailyRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.quest_daily_reward_receive_req) 10 | public class HandlerQuestDailyRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = UI32.parseFrom(message); 16 | 17 | // Receive rewards 18 | var change = session.getPlayer().getQuestManager().receiveQuestReward(req.getValue()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.quest_daily_reward_receive_failed_ack); 22 | } 23 | 24 | // Template 25 | return session.encodeMsg(NetMsgId.quest_daily_reward_receive_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DiscDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.character.ElementType; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "Disc.json") 10 | public class DiscDef extends BaseDef { 11 | private int Id; 12 | private boolean Visible; 13 | private boolean Available; 14 | private int EET; 15 | 16 | private int StrengthenGroupId; 17 | private int PromoteGroupId; 18 | private int TransformItemId; 19 | private int[] MaxStarTransformItem; 20 | private int[] ReadReward; 21 | 22 | private int SecondarySkillGroupId1; 23 | private int SecondarySkillGroupId2; 24 | private int SubNoteSkillGroupId; 25 | 26 | private transient ElementType elementType; 27 | 28 | @Override 29 | public int getId() { 30 | return Id; 31 | } 32 | 33 | @Override 34 | public void onLoad() { 35 | this.elementType = ElementType.getByValue(this.EET); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import java.util.Arrays; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "StarTower.json") 12 | public class StarTowerDef extends BaseDef { 13 | private int Id; 14 | private int GroupId; 15 | private int Difficulty; 16 | private int SubNoteSkillDropGroupId; 17 | private int[] FloorNum; 18 | 19 | private transient int maxFloors; 20 | 21 | @Override 22 | public int getId() { 23 | return Id; 24 | } 25 | 26 | public int getMaxFloor(int stageNum) { 27 | int index = stageNum - 1; 28 | 29 | if (index < 0 || index >= this.FloorNum.length) { 30 | return 0; 31 | } 32 | 33 | return this.FloorNum[index]; 34 | } 35 | 36 | @Override 37 | public void onLoad() { 38 | this.maxFloors = Arrays.stream(this.FloorNum).reduce(0, Integer::sum); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TalentDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "Talent.json", loadPriority = LoadPriority.LOW) 11 | public class TalentDef extends BaseDef { 12 | private int Id; 13 | private int Index; 14 | private int Type; 15 | private int GroupId; 16 | private int Sort; 17 | 18 | @Override 19 | public int getId() { 20 | return Id; 21 | } 22 | 23 | @Override 24 | public void onLoad() { 25 | var talentGroup = GameData.getTalentGroupDataTable().get(this.getGroupId()); 26 | if (talentGroup == null) { 27 | return; 28 | } 29 | 30 | if (this.Type == 1) { 31 | talentGroup.setMainTalent(this); 32 | } else if (this.Type == 2) { 33 | talentGroup.getTalents().add(this); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerTowerGrowthNodeUnlockReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.tower_growth_node_unlock_req) 10 | public class HandlerTowerGrowthNodeUnlockReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = UI32.parseFrom(message); 16 | 17 | // Unlock tower growth node 18 | var change = session.getPlayer().getStarTowerManager().unlockGrowthNode(req.getValue()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.tower_growth_node_unlock_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.tower_growth_node_unlock_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerTutorialLevelSettleReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.Nebula; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.tutorial_level_settle_req) 11 | public class HandlerTutorialLevelSettleReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = UI32.parseFrom(message); 17 | 18 | // Settle 19 | boolean success = Nebula.getGameContext().getTutorialModule().settle(session.getPlayer(), req.getValue()); 20 | 21 | if (success == false) { 22 | return session.encodeMsg(NetMsgId.tutorial_level_settle_failed_ack); 23 | } 24 | 25 | // Encode and send 26 | return session.encodeMsg(NetMsgId.tutorial_level_settle_succeed_ack); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerVampireTalentDetailReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.VampireTalentDetail.VampireTalentDetailResp; 6 | import emu.nebula.net.HandlerId; 7 | 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.vampire_talent_detail_req) 11 | public class HandlerVampireTalentDetailReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Get vampire surv manager 16 | var manager = session.getPlayer().getVampireSurvivorManager(); 17 | 18 | // Build response 19 | var rsp = VampireTalentDetailResp.newInstance() 20 | .setNodes(manager.getTalents().toByteArray()) 21 | .setActiveCount(manager.getProgress().getFateCards().size()); 22 | 23 | // Encode and send 24 | return session.encodeMsg(NetMsgId.vampire_talent_detail_succeed_ack, rsp); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | [%d{HH:mm:ss}] [%level] %msg%n 5 | 6 | 7 | 8 | logs/latest.log 9 | 10 | logs/log.%d{yyyy-MM-dd}_%d{HH}.log.gz 11 | 24 12 | 13 | 14 | [%d{yyyy-MM-dd HH:mm:ss}] [%level] %msg%n 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerInfinityTowerApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.InfinityTowerApply.InfinityTowerApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.infinity_tower_apply_req) 10 | public class HandlerInfinityTowerApplyReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Template hanlder 15 | var req = InfinityTowerApplyReq.parseFrom(message); 16 | 17 | // Apply 18 | boolean success = session.getPlayer().getInfinityTowerManager().apply(req.getLevelId(), req.getBuildId()); 19 | 20 | if (!success) { 21 | return session.encodeMsg(NetMsgId.infinity_tower_apply_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.infinity_tower_apply_succeed_ack); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStarTowerBuildBriefListGetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StarTowerBuildBriefListGet.StarTowerBuildBriefListGetResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.star_tower_build_brief_list_get_req) 10 | public class HandlerStarTowerBuildBriefListGetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Build response 15 | var rsp = StarTowerBuildBriefListGetResp.newInstance(); 16 | 17 | // Add star tower builds 18 | var builds = session.getPlayer().getStarTowerManager().getBuilds().values(); 19 | for (var build : builds) { 20 | rsp.addBriefs(build.toBriefProto()); 21 | } 22 | 23 | // Finish 24 | return session.encodeMsg(NetMsgId.star_tower_build_brief_list_get_succeed_ack, rsp); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaGuaranteeRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.gacha_guarantee_reward_receive_req) 10 | public class HandlerGachaGuaranteeRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse req 15 | var req = UI32.parseFrom(message); 16 | 17 | // Recieve guaranteed reward 18 | var change = session.getPlayer().getGachaManager().recvGuarantee(req.getValue()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.gacha_guarantee_reward_receive_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.gacha_guarantee_reward_receive_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ActivityTaskDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "ActivityTask.json") 10 | public class ActivityTaskDef extends BaseDef { 11 | private int Id; 12 | private int ActivityTaskGroupId; 13 | 14 | private int CompleteCond; 15 | private int AimNumShow; 16 | 17 | private int Tid1; 18 | private int Qty1; 19 | private int Tid2; 20 | private int Qty2; 21 | 22 | private transient ItemParamMap rewards; 23 | 24 | @Override 25 | public int getId() { 26 | return Id; 27 | } 28 | 29 | @Override 30 | public void onLoad() { 31 | this.rewards = new ItemParamMap(); 32 | 33 | if (this.Tid1 > 0) { 34 | this.rewards.add(this.Tid1, this.Qty1); 35 | } 36 | if (this.Tid2 > 0) { 37 | this.rewards.add(this.Tid2, this.Qty2); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DailyQuestActiveDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "DailyQuestActive.json") 10 | public class DailyQuestActiveDef extends BaseDef { 11 | private int Id; 12 | private int Active; 13 | 14 | private int ItemTid1; 15 | private int Number1; 16 | private int ItemTid2; 17 | private int Number2; 18 | 19 | private transient ItemParamMap rewards; 20 | 21 | @Override 22 | public int getId() { 23 | return Id; 24 | } 25 | 26 | @Override 27 | public void onLoad() { 28 | this.rewards = new ItemParamMap(); 29 | 30 | if (this.ItemTid1 > 0 && this.Number1 > 0) { 31 | this.rewards.add(this.ItemTid1, this.Number1); 32 | } 33 | if (this.ItemTid2 > 0 && this.Number2 > 0) { 34 | this.rewards.add(this.ItemTid2, this.Number2); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPhoneContactsTopReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.phone_contacts_top_req) 10 | public class HandlerPhoneContactsTopReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = UI32.parseFrom(message); 16 | 17 | // Get character 18 | var character = session.getPlayer().getCharacters().getCharacterById(req.getValue()); 19 | if (character == null) { 20 | return session.encodeMsg(NetMsgId.phone_contacts_top_failed_ack); 21 | } 22 | 23 | // Toggle chat status 24 | character.getContact().toggleTop(); 25 | 26 | // Encode and send 27 | return session.encodeMsg(NetMsgId.phone_contacts_top_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/FileUtils.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | import java.nio.file.Path; 7 | import java.nio.file.Paths; 8 | 9 | import emu.nebula.Nebula; 10 | 11 | public class FileUtils { 12 | public static void write(String dest, byte[] bytes) { 13 | Path path = Paths.get(dest); 14 | 15 | try { 16 | Files.write(path, bytes); 17 | } catch (IOException e) { 18 | Nebula.getLogger().warn("Failed to write file: " + dest); 19 | } 20 | } 21 | 22 | public static byte[] read(String dest) { 23 | return read(Paths.get(dest)); 24 | } 25 | 26 | public static byte[] read(Path path) { 27 | try { 28 | return Files.readAllBytes(path); 29 | } catch (IOException e) { 30 | Nebula.getLogger().warn("Failed to read file: " + path); 31 | } 32 | 33 | return new byte[0]; 34 | } 35 | 36 | public static byte[] read(File file) { 37 | return read(file.getPath()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMallPackageListReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MallPackageListOuterClass.MallPackageList; 6 | import emu.nebula.proto.MallPackageListOuterClass.PackageInfo; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.data.GameData; 9 | import emu.nebula.net.GameSession; 10 | 11 | @HandlerId(NetMsgId.mall_package_list_req) 12 | public class HandlerMallPackageListReq extends NetHandler { 13 | 14 | @Override 15 | public byte[] handle(GameSession session, byte[] message) throws Exception { 16 | var rsp = MallPackageList.newInstance(); 17 | 18 | for (var data : GameData.getMallPackageDataTable()) { 19 | var info = PackageInfo.newInstance() 20 | .setId(data.getIdString()) 21 | .setStock(data.getStock()); 22 | 23 | rsp.addList(info); 24 | } 25 | 26 | return session.encodeMsg(NetMsgId.mall_package_list_succeed_ack, rsp); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/PatchList.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server; 2 | 3 | import java.util.List; 4 | 5 | import emu.nebula.proto.Pb.ClientDiff; 6 | import emu.nebula.proto.Pb.FileDiff; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class PatchList { 11 | public long version; 12 | public List files; 13 | 14 | @Getter 15 | public static class PatchListFile { 16 | public String name; 17 | public String hash; 18 | public long version; 19 | public String additionalPath; 20 | } 21 | 22 | // Proto 23 | 24 | public ClientDiff toProto() { 25 | var proto = ClientDiff.newInstance(); 26 | 27 | for (var file : files) { 28 | var diff = FileDiff.newInstance() 29 | .setFileName(file.getName()) 30 | .setHash(file.getHash()) 31 | .setVersion(this.getVersion()) 32 | .setAdditionalPath(file.getAdditionalPath()); 33 | 34 | proto.addDiff(diff); 35 | } 36 | 37 | return proto; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerAchievementRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.AchievementRewardReceive.AchievementRewardReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.achievement_reward_receive_req) 10 | public class HandlerAchievementRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = AchievementRewardReq.parseFrom(message); 16 | 17 | // Claim rewards 18 | var change = session.getPlayer().getAchievementManager().recvRewards(req.getIds()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.achievement_reward_receive_failed_ack); 22 | } 23 | 24 | // Encode and send 25 | return session.encodeMsg(NetMsgId.achievement_reward_receive_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/cases/StarTowerRecoveryHPCase.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.cases; 2 | 3 | import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; 4 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; 5 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class StarTowerRecoveryHPCase extends StarTowerBaseCase { 10 | 11 | @Override 12 | public CaseType getType() { 13 | return CaseType.RecoveryHP; 14 | } 15 | 16 | @Override 17 | public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { 18 | // Set nil resp 19 | rsp.getMutableNilResp(); 20 | 21 | // Add sync hp case 22 | this.getGame().addCase(rsp.getMutableCases(), new StarTowerSyncHPCase()); 23 | 24 | // Return 25 | return rsp; 26 | } 27 | 28 | // Proto 29 | 30 | @Override 31 | public void encodeProto(StarTowerRoomCase proto) { 32 | // Set field in the proto 33 | proto.getMutableRecoveryHPCase(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendRecommendationGetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendRecommendationGet.FriendRecommendationGetResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.Nebula; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.friend_recommendation_get_req) 11 | public class HandlerFriendRecommendationGetReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Build response 16 | var rsp = FriendRecommendationGetResp.newInstance(); 17 | 18 | // Get players 19 | var players = Nebula.getGameContext().getPlayerModule().getRandomPlayerList(session.getPlayer()); 20 | 21 | for (var player : players) { 22 | rsp.addFriends(player.getFriendProto()); 23 | } 24 | 25 | // Encode and send 26 | return session.encodeMsg(NetMsgId.friend_recommendation_get_succeed_ack, rsp); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMallMonthlyCardListReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MallMonthlycardList.MallMonthlyCardList; 6 | import emu.nebula.proto.MallMonthlycardList.MonthlyCardInfo; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.data.GameData; 9 | import emu.nebula.net.GameSession; 10 | 11 | @HandlerId(NetMsgId.mall_monthlyCard_list_req) 12 | public class HandlerMallMonthlyCardListReq extends NetHandler { 13 | 14 | @Override 15 | public byte[] handle(GameSession session, byte[] message) throws Exception { 16 | var rsp = MallMonthlyCardList.newInstance(); 17 | 18 | for (var data : GameData.getMallMonthlyCardDataTable()) { 19 | var info = MonthlyCardInfo.newInstance() 20 | .setId(data.getIdString()) 21 | .setRemaining(9); 22 | 23 | rsp.addList(info); 24 | } 25 | 26 | return session.encodeMsg(NetMsgId.mall_monthlyCard_list_succeed_ack, rsp); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerTutorialLevelRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.Nebula; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.tutorial_level_reward_receive_req) 11 | public class HandlerTutorialLevelRewardReceiveReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = UI32.parseFrom(message); 17 | 18 | // Get rewards 19 | var change = Nebula.getGameContext().getTutorialModule().recvReward(session.getPlayer(), req.getValue()); 20 | 21 | if (change == null) { 22 | return session.encodeMsg(NetMsgId.tutorial_level_reward_receive_failed_ack); 23 | } 24 | 25 | // Encode and send 26 | return session.encodeMsg(NetMsgId.tutorial_level_reward_receive_succeed_ack, change.toProto()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMailRemoveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MailRemove.MailRemoveResp; 6 | import emu.nebula.proto.Public.MailRequest; 7 | import it.unimi.dsi.fastutil.ints.IntList; 8 | import emu.nebula.net.HandlerId; 9 | import emu.nebula.net.GameSession; 10 | 11 | @HandlerId(NetMsgId.mail_remove_req) 12 | public class HandlerMailRemoveReq extends NetHandler { 13 | 14 | @Override 15 | public byte[] handle(GameSession session, byte[] message) throws Exception { 16 | // Parse request 17 | var req = MailRequest.parseFrom(message); 18 | 19 | // Claim mail 20 | IntList removed = session.getPlayer().getMailbox().removeMail(session.getPlayer(), req.getId()); 21 | 22 | // Build response 23 | var rsp = MailRemoveResp.newInstance(); 24 | 25 | for (int id : removed) { 26 | rsp.addIds(id); 27 | } 28 | 29 | return session.encodeMsg(NetMsgId.mail_remove_succeed_ack, rsp); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/inventory/ItemType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.inventory; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum ItemType { 8 | Res (1), 9 | Item (2), 10 | Char (3), 11 | Energy (4), 12 | WorldRankExp (5), 13 | RogueItem (6), 14 | Disc (7), 15 | Equipment (9), 16 | CharacterSkin (10), 17 | MonthlyCard (11), 18 | Title (12), 19 | Honor (13), 20 | HeadItem (14); 21 | 22 | @Getter 23 | private final int value; 24 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 25 | 26 | static { 27 | for (ItemType type : ItemType.values()) { 28 | map.put(type.getValue(), type); 29 | } 30 | } 31 | 32 | private ItemType(int value) { 33 | this.value = value; 34 | } 35 | 36 | public static ItemType getByValue(int value) { 37 | return map.get(value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStarTowerInteractReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.star_tower_interact_req) 10 | public class HandlerStarTowerInteractReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Get star tower instance 15 | var game = session.getPlayer().getStarTowerManager().getGame(); 16 | 17 | if (game == null) { 18 | return session.encodeMsg(NetMsgId.star_tower_interact_failed_ack); 19 | } 20 | 21 | // Parse request 22 | var req = StarTowerInteractReq.parseFrom(message); 23 | 24 | // Handle interaction 25 | var rsp = game.handleInteract(req); 26 | 27 | // Send response 28 | return session.encodeMsg(NetMsgId.star_tower_interact_succeed_ack, rsp); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/activity/ActivityType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.activity; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum ActivityType { 8 | None (0), 9 | PeriodicQuest (1), 10 | LoginReward (2), 11 | Mining (3), 12 | Cookie (4), 13 | TowerDefense (5), 14 | Trial (6), 15 | JointDrill (7), 16 | CG (8), 17 | Levels (9), 18 | Avg (10), 19 | Task (11), 20 | Shop (12), 21 | Advertise (13); 22 | 23 | @Getter 24 | private final int value; 25 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 26 | 27 | static { 28 | for (ActivityType type : ActivityType.values()) { 29 | map.put(type.getValue(), type); 30 | } 31 | } 32 | 33 | private ActivityType(int value) { 34 | this.value = value; 35 | } 36 | 37 | public static ActivityType getByValue(int value) { 38 | return map.get(value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerTowerBookFateCardDetailReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.TowerBookFateCardDetail.TowerBookFateCardDetailResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.tower_book_fate_card_detail_req) 11 | public class HandlerTowerBookFateCardDetailReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Build response 16 | var rsp = TowerBookFateCardDetailResp.newInstance(); 17 | 18 | for (int card : session.getPlayer().getProgress().getFateCards()) { 19 | rsp.addCards(card); 20 | } 21 | 22 | for (var quest : GameData.getStarTowerBookFateCardQuestDataTable()) { 23 | rsp.addQuests(quest.getId()); 24 | } 25 | 26 | // Encode and send 27 | return session.encodeMsg(NetMsgId.tower_book_fate_card_detail_succeed_ack, rsp); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/room/StarTowerHawkerRoom.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.room; 2 | 3 | import emu.nebula.data.resources.StarTowerStageDef; 4 | import emu.nebula.game.tower.StarTowerGame; 5 | import emu.nebula.game.tower.cases.StarTowerHawkerCase; 6 | import emu.nebula.game.tower.cases.StarTowerStrengthenMachineCase; 7 | import emu.nebula.game.tower.cases.StarTowerSyncHPCase; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | public class StarTowerHawkerRoom extends StarTowerBaseRoom { 12 | 13 | public StarTowerHawkerRoom(StarTowerGame game, StarTowerStageDef stage) { 14 | super(game, stage); 15 | } 16 | 17 | @Override 18 | public void onEnter() { 19 | // Create hawker case (shop) 20 | this.addCase(new StarTowerHawkerCase()); 21 | 22 | // Create strengthen machine 23 | if (this.getModifiers().isEnableShopStrengthen()) { 24 | this.addCase(new StarTowerStrengthenMachineCase()); 25 | } 26 | 27 | // Create sync hp case 28 | this.addCase(new StarTowerSyncHPCase()); 29 | 30 | // Create door case 31 | this.createExit(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerPlayerWorldClassRewardReceiveReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.PlayerWorldClassRewardReceive.PlayerWorldClassRewardReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.player_world_class_reward_receive_req) 10 | public class HandlerPlayerWorldClassRewardReceiveReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = PlayerWorldClassRewardReq.parseFrom(message); 16 | 17 | // Receive rewards 18 | var change = session.getPlayer().getQuestManager().receiveWorldClassReward(req.getClassX()); 19 | 20 | if (change == null) { 21 | return session.encodeMsg(NetMsgId.player_world_class_reward_receive_failed_ack); 22 | } 23 | 24 | // Template 25 | return session.encodeMsg(NetMsgId.player_world_class_reward_receive_succeed_ack, change.toProto()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StarTowerBookFateCardDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "StarTowerBookFateCard.json", loadPriority = LoadPriority.LOW) 11 | public class StarTowerBookFateCardDef extends BaseDef { 12 | private int Id; 13 | private int BundleId; 14 | 15 | @Override 16 | public int getId() { 17 | return Id; 18 | } 19 | 20 | @Override 21 | public void onLoad() { 22 | // Set card bundle id 23 | var card = GameData.getFateCardDataTable().get(this.getId()); 24 | if (card == null) { 25 | return; 26 | } 27 | 28 | card.setBundleId(this.BundleId); 29 | 30 | // Add to bundle 31 | var bundle = GameData.getStarTowerBookFateCardBundleDataTable().get(this.getBundleId()); 32 | if (bundle == null) { 33 | return; 34 | } 35 | 36 | bundle.addCard(card); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/TrialGroupDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "TrialGroup.json") 10 | public class TrialGroupDef extends BaseDef { 11 | private int Id; 12 | 13 | private int RewardId1; 14 | private int Qty1; 15 | private int RewardId2; 16 | private int Qty2; 17 | private int RewardId3; 18 | private int Qty3; 19 | 20 | private transient ItemParamMap rewards; 21 | 22 | @Override 23 | public int getId() { 24 | return Id; 25 | } 26 | 27 | @Override 28 | public void onLoad() { 29 | this.rewards = new ItemParamMap(); 30 | 31 | if (this.RewardId1 > 0) { 32 | this.rewards.add(this.RewardId1, this.Qty1); 33 | } 34 | if (this.RewardId2 > 0) { 35 | this.rewards.add(this.RewardId2, this.Qty2); 36 | } 37 | if (this.RewardId3 > 0) { 38 | this.rewards.add(this.RewardId3, this.Qty3); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStarTowerBuildLockUnlockReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StarTowerBuildLockUnlock.StarTowerBuildLockUnlockReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.star_tower_build_lock_unlock_req) 10 | public class HandlerStarTowerBuildLockUnlockReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = StarTowerBuildLockUnlockReq.parseFrom(message); 16 | 17 | // Get build 18 | var build = session.getPlayer().getStarTowerManager().getBuildById(req.getBuildId()); 19 | 20 | if (build == null) { 21 | return session.encodeMsg(NetMsgId.star_tower_build_lock_unlock_failed_ack); 22 | } 23 | 24 | build.setLock(req.getLock()); 25 | 26 | // Encode packet 27 | return session.encodeMsg(NetMsgId.star_tower_build_lock_unlock_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerCharAdvanceReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.Public.UI32; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.char_advance_req) 10 | public class HandlerCharAdvanceReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var req = UI32.parseFrom(message); 15 | 16 | // Get character 17 | var character = session.getPlayer().getCharacters().getCharacterById(req.getValue()); 18 | 19 | if (character == null) { 20 | return session.encodeMsg(NetMsgId.char_advance_failed_ack); 21 | } 22 | 23 | // Advance character 24 | var change = character.advance(); 25 | 26 | if (change == null) { 27 | return session.encodeMsg(NetMsgId.char_advance_failed_ack); 28 | } 29 | 30 | return session.encodeMsg(NetMsgId.char_advance_succeed_ack, change.toProto()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerWeekBossApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.WeekBossApply.WeekBossApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.week_boss_apply_req) 11 | public class HandlerWeekBossApplyReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = WeekBossApplyReq.parseFrom(message); 17 | 18 | var data = GameData.getWeekBossLevelDataTable().get(req.getId()); 19 | if (data == null || !data.hasEnergy(session.getPlayer())) { 20 | return session.encodeMsg(NetMsgId.week_boss_apply_failed_ack); 21 | } 22 | 23 | // Set player instance id 24 | session.getPlayer().getInstanceManager().setCurInstanceId(req.getId()); 25 | 26 | // Send response 27 | return session.encodeMsg(NetMsgId.week_boss_apply_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ActivityGoodsDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import emu.nebula.game.inventory.ItemParamMap; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "ActivityGoods.json", loadPriority = LoadPriority.LOW) 12 | public class ActivityGoodsDef extends BaseDef { 13 | private int Id; 14 | private int ShopId; 15 | 16 | private int ItemId; 17 | private int ItemQuantity; 18 | private int MaximumLimit; 19 | private int Price; 20 | 21 | private transient ItemParamMap items; 22 | 23 | @Override 24 | public int getId() { 25 | return Id; 26 | } 27 | 28 | @Override 29 | public void onLoad() { 30 | var shop = GameData.getActivityShopDataTable().get(this.getShopId()); 31 | if (shop != null) { 32 | shop.getGoods().put(this.getId(), this); 33 | } 34 | 35 | this.items = new ItemParamMap(); 36 | this.items.add(this.ItemId, this.ItemQuantity); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/vampire/VampireSurvivorLog.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.vampire; 2 | 3 | import dev.morphia.annotations.Entity; 4 | import emu.nebula.proto.Public.VampireSurvivorLevel; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Entity(useDiscriminator = false) 10 | public class VampireSurvivorLog { 11 | private int id; 12 | 13 | @Setter private int score; 14 | @Setter private boolean passed; 15 | @Setter private long[] builds; 16 | 17 | @Deprecated // Morphia only 18 | public VampireSurvivorLog() { 19 | 20 | } 21 | 22 | public VampireSurvivorLog(int id) { 23 | this.id = id; 24 | } 25 | 26 | // Proto 27 | 28 | public VampireSurvivorLevel toProto() { 29 | var proto = VampireSurvivorLevel.newInstance() 30 | .setId(this.getId()) 31 | .setScore(this.getScore()) 32 | .setPassed(this.isPassed()); 33 | 34 | if (this.builds != null) { 35 | for (long buildId : this.builds) { 36 | proto.addBuildIds(buildId); 37 | } 38 | } 39 | 40 | return proto; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerGachaHistoriesReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.GachaHistoriesOuterClass.GachaHistories; 6 | import emu.nebula.proto.Public.UI32; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.gacha_histories_req) 11 | public class HandlerGachaHistoriesReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = UI32.parseFrom(message); 17 | 18 | // Get history log 19 | var list = session.getPlayer().getGachaManager().getHistories().get(req.getValue()); 20 | 21 | // Build response 22 | var rsp = GachaHistories.newInstance(); 23 | 24 | if (list != null) { 25 | for (var log : list) { 26 | rsp.addList(log.toProto()); 27 | } 28 | } 29 | 30 | // Encode and send 31 | return session.encodeMsg(NetMsgId.gacha_histories_succeed_ack, rsp); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerStarTowerGiveUpReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.StarTowerGiveUp.StarTowerGiveUpResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.star_tower_give_up_req) 10 | public class HandlerStarTowerGiveUpReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var game = session.getPlayer().getStarTowerManager().settleGame(false); 15 | 16 | if (game == null) { 17 | return session.encodeMsg(NetMsgId.star_tower_give_up_failed_ack); 18 | } 19 | 20 | // Build response 21 | var rsp = StarTowerGiveUpResp.newInstance() 22 | .setBuild(game.getBuild().toProto()) 23 | .setPotentialCnt(game.getTotalPotentialCount()) 24 | .setFloor(game.getFloorCount()); 25 | 26 | rsp.getMutableChange(); 27 | 28 | return session.encodeMsg(NetMsgId.star_tower_give_up_succeed_ack, rsp); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/ResidentGoodsDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import emu.nebula.game.player.Player; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "ResidentGoods.json") 11 | public class ResidentGoodsDef extends BaseDef { 12 | private int Id; 13 | private int ShopId; 14 | private int MaximumLimit; 15 | 16 | private int ItemId; 17 | private int ItemQuantity; 18 | 19 | private int CurrencyItemId; 20 | private int Price; 21 | 22 | private transient ItemParamMap products; 23 | 24 | @Override 25 | public int getId() { 26 | return Id; 27 | } 28 | 29 | public int getStock(Player player) { 30 | return Math.max(this.getMaximumLimit() - player.getInventory().getMallBuyCount().getInt(this.getId()), 0); 31 | } 32 | 33 | @Override 34 | public void onLoad() { 35 | this.products = new ItemParamMap(); 36 | 37 | if (this.ItemId > 0) { 38 | this.products.add(this.ItemId, this.ItemQuantity); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerAgentGiveUpReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.AgentGiveUp.AgentGiveUpReq; 6 | import emu.nebula.proto.AgentGiveUp.AgentGiveUpResp; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.agent_give_up_req) 11 | public class HandlerAgentGiveUpReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = AgentGiveUpReq.parseFrom(message); 17 | 18 | // Give up 19 | var agent = session.getPlayer().getAgentManager().giveUp(req.getId()); 20 | 21 | if (agent == null) { 22 | return session.encodeMsg(NetMsgId.agent_give_up_failed_ack); 23 | } 24 | 25 | // Build response 26 | var rsp = AgentGiveUpResp.newInstance() 27 | .addAllCharIds(agent.getCharIds()); 28 | 29 | // Encode and send 30 | return session.encodeMsg(NetMsgId.agent_give_up_succeed_ack, rsp); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/activity/ActivityModule.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.activity; 2 | 3 | import emu.nebula.game.GameContext; 4 | import emu.nebula.game.GameContextModule; 5 | import it.unimi.dsi.fastutil.ints.IntArrayList; 6 | import it.unimi.dsi.fastutil.ints.IntList; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | public class ActivityModule extends GameContextModule { 11 | private IntList activities; 12 | 13 | public ActivityModule(GameContext context) { 14 | super(context); 15 | this.activities = new IntArrayList(); 16 | 17 | // Hardcode these activities for now 18 | // TODO make an activity json file to read activity ids from 19 | 20 | // Trial activities 21 | this.activities.add(700104); 22 | this.activities.add(700107); 23 | this.activities.add(700108); 24 | 25 | // Tower defense activity 26 | this.activities.add(102001); 27 | 28 | // 29 | this.activities.add(1010201); 30 | this.activities.add(1010203); 31 | this.activities.add(1010204); 32 | 33 | //this.activities.add(101002); 34 | //this.activities.add(101003); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | #idea 5 | *.idea 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.war 17 | *.nar 18 | *.ear 19 | *.zip 20 | *.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | 26 | # Ignore Gradle project-specific cache directory 27 | .gradle 28 | 29 | # Ignore Gradle build output directory 30 | build/ 31 | out/ 32 | 33 | # Ignore Gradle properties 34 | gradle.properties 35 | 36 | # Eclipse 37 | .project 38 | .classpath 39 | .settings 40 | .metadata 41 | .properties 42 | bin/ 43 | tmp/ 44 | *.tmp 45 | *.bak 46 | *.swp 47 | *~.nib 48 | .loadpath 49 | .recommenders 50 | 51 | # VSCode 52 | .vscode 53 | 54 | # lombok 55 | /.apt_generated/ 56 | 57 | # macOS 58 | .DS_Store 59 | .directory 60 | 61 | # Generated/resource/log/plugins/etc folders 62 | /logs 63 | /plugins 64 | /proto 65 | /resources 66 | /web 67 | /StellaSoraData 68 | 69 | # Compiled 70 | /*.jar 71 | /*.sh 72 | 73 | # Extra 74 | Nebula Handbook.txt 75 | config.json 76 | patchlist.json 77 | *.mv 78 | *.exe 79 | *.p12 80 | BuildConfig.java 81 | Test.java -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/cases/StarTowerNpcRecoveryHPCase.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.cases; 2 | 3 | import emu.nebula.proto.PublicStarTower.StarTowerRoomCase; 4 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractReq; 5 | import emu.nebula.proto.StarTowerInteract.StarTowerInteractResp; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | public class StarTowerNpcRecoveryHPCase extends StarTowerBaseCase { 10 | private int effectId; 11 | 12 | public StarTowerNpcRecoveryHPCase() { 13 | this(989970); // Restore Hp/Energy by 50% 14 | } 15 | 16 | public StarTowerNpcRecoveryHPCase(int effectId) { 17 | this.effectId = effectId; 18 | } 19 | 20 | @Override 21 | public CaseType getType() { 22 | return CaseType.NpcRecoveryHP; 23 | } 24 | 25 | @Override 26 | public StarTowerInteractResp interact(StarTowerInteractReq req, StarTowerInteractResp rsp) { 27 | return rsp; 28 | } 29 | 30 | // Proto 31 | 32 | @Override 33 | public void encodeProto(StarTowerRoomCase proto) { 34 | // Set case info 35 | proto.getMutableNpcRecoveryHPCase() 36 | .setEffectId(this.getEffectId()); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerSkillInstanceApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.SkillInstanceApply.SkillInstanceApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.skill_instance_apply_req) 11 | public class HandlerSkillInstanceApplyReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = SkillInstanceApplyReq.parseFrom(message); 17 | 18 | var data = GameData.getSkillInstanceDataTable().get(req.getId()); 19 | if (data == null || !data.hasEnergy(session.getPlayer())) { 20 | return session.encodeMsg(NetMsgId.skill_instance_apply_failed_ack); 21 | } 22 | 23 | // Set player instance id 24 | session.getPlayer().getInstanceManager().setCurInstanceId(req.getId()); 25 | 26 | // Send response 27 | return session.encodeMsg(NetMsgId.skill_instance_apply_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerCharSkinSetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.CharSkinSet.CharSkinSetReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.char_skin_set_req) 10 | public class HandlerCharSkinSetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = CharSkinSetReq.parseFrom(message); 16 | 17 | // Get character 18 | var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId()); 19 | if (character == null) { 20 | return session.encodeMsg(NetMsgId.char_skin_set_failed_ack); 21 | } 22 | 23 | // Set skin 24 | var result = character.setSkin(req.getSkinId()); 25 | if (!result) { 26 | return session.encodeMsg(NetMsgId.char_skin_set_failed_ack); 27 | } 28 | 29 | // Encode and send 30 | return session.encodeMsg(NetMsgId.char_skin_set_succeed_ack); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/StorySetSectionDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import it.unimi.dsi.fastutil.ints.IntOpenHashSet; 7 | import it.unimi.dsi.fastutil.ints.IntSet; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | @ResourceType(name = "StorySetSection.json") 12 | public class StorySetSectionDef extends BaseDef { 13 | private int Id; 14 | private int ChapterId; 15 | 16 | private int RewardItem1Tid; 17 | private int RewardItem1Qty; 18 | 19 | private transient ItemParamMap rewards; 20 | 21 | @Getter 22 | private static IntSet chapterIds = new IntOpenHashSet(); 23 | 24 | @Override 25 | public int getId() { 26 | return Id; 27 | } 28 | 29 | @Override 30 | public void onLoad() { 31 | // Add to chapter ids 32 | chapterIds.add(this.getChapterId()); 33 | 34 | // Parse rewards 35 | this.rewards = new ItemParamMap(); 36 | 37 | if (this.RewardItem1Tid > 0) { 38 | this.rewards.add(this.RewardItem1Tid, this.RewardItem1Qty); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/dating/DatingManager.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.dating; 2 | 3 | import emu.nebula.data.GameData; 4 | import emu.nebula.game.character.GameCharacter; 5 | import emu.nebula.game.player.Player; 6 | import emu.nebula.game.player.PlayerManager; 7 | import emu.nebula.game.quest.QuestCondition; 8 | import lombok.Getter; 9 | 10 | @Getter 11 | public class DatingManager extends PlayerManager { 12 | private DatingGame game; 13 | 14 | public DatingManager(Player player) { 15 | super(player); 16 | } 17 | 18 | public DatingGame selectLandmark(GameCharacter character, int landmarkId) { 19 | // Get landmark data 20 | var data = GameData.getDatingLandmarkDataTable().get(landmarkId); 21 | 22 | if (data == null) { 23 | return null; 24 | } 25 | 26 | // Set landmark + character 27 | this.game = new DatingGame(character, data); 28 | 29 | // Trigger quest/achievement 30 | this.getPlayer().trigger(QuestCondition.CharactersDatingTotal, 1); 31 | 32 | // Success 33 | return this.game; 34 | } 35 | 36 | public void endDatingGame() { 37 | this.game = null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/gacha/GachaHistoryLog.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.gacha; 2 | 3 | import dev.morphia.annotations.Entity; 4 | import emu.nebula.Nebula; 5 | import emu.nebula.proto.GachaHistoriesOuterClass.GachaHistory; 6 | import it.unimi.dsi.fastutil.ints.IntList; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @Entity(value = "banner_info", useDiscriminator = false) 11 | public class GachaHistoryLog { 12 | private int type; 13 | private int gid; 14 | private long time; 15 | private IntList ids; 16 | 17 | @Deprecated // Morphia only 18 | public GachaHistoryLog() { 19 | 20 | } 21 | 22 | public GachaHistoryLog(int type, int gachaId, IntList results) { 23 | this.type = type; 24 | this.gid = gachaId; 25 | this.time = Nebula.getCurrentTime(); 26 | this.ids = results; 27 | } 28 | 29 | // Proto 30 | 31 | public GachaHistory toProto() { 32 | var proto = GachaHistory.newInstance() 33 | .setGid(this.getGid()) 34 | .setTime(this.getTime()); 35 | 36 | for (int id : this.getIds()) { 37 | proto.addIds(id); 38 | } 39 | 40 | return proto; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/character/ElementType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.character; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public enum ElementType { 9 | INHERIT (0), 10 | AQUA (1, 90018), 11 | FIRE (2, 90019), 12 | EARTH (3, 90021), 13 | WIND (4, 90020), 14 | LIGHT (5, 90022), 15 | DARK (6, 90023), 16 | NONE (7); 17 | 18 | private final int value; 19 | private final int subNoteSkillItemId; 20 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 21 | 22 | static { 23 | for (ElementType type : ElementType.values()) { 24 | map.put(type.getValue(), type); 25 | } 26 | } 27 | 28 | private ElementType(int value) { 29 | this(value, 0); 30 | } 31 | 32 | private ElementType(int value, int subNoteSkillItemId) { 33 | this.value = value; 34 | this.subNoteSkillItemId = subNoteSkillItemId; 35 | } 36 | 37 | public static ElementType getByValue(int value) { 38 | return map.get(value); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerCharGemInstanceApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.CharGemInstanceApply.CharGemInstanceApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.char_gem_instance_apply_req) 11 | public class HandlerCharGemInstanceApplyReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = CharGemInstanceApplyReq.parseFrom(message); 17 | 18 | var data = GameData.getCharGemInstanceDataTable().get(req.getId()); 19 | if (data == null || !data.hasEnergy(session.getPlayer())) { 20 | return session.encodeMsg(NetMsgId.char_gem_instance_apply_failed_ack); 21 | } 22 | 23 | // Set player instance id 24 | session.getPlayer().getInstanceManager().setCurInstanceId(req.getId()); 25 | 26 | // Send response 27 | return session.encodeMsg(NetMsgId.char_gem_instance_apply_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerEnergyBuyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.EnergyBuy.EnergyBuyResp; 6 | import emu.nebula.proto.Public.UI32; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.energy_buy_req) 11 | public class HandlerEnergyBuyReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = UI32.parseFrom(message); 17 | 18 | // Buy energy 19 | var change = session.getPlayer().getInventory().buyEnergy(req.getValue()); 20 | 21 | if (change == null) { 22 | return session.encodeMsg(NetMsgId.energy_buy_failed_ack); 23 | } 24 | 25 | // Build response 26 | var rsp = EnergyBuyResp.newInstance() 27 | .setChange(change.toProto()) 28 | .setCount(0); // TODO max energy buy count per day 29 | 30 | // Encode and send 31 | return session.encodeMsg(NetMsgId.energy_buy_succeed_ack, rsp); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerRegionBossLevelApplyReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.RegionBossLevelApply.RegionBossLevelApplyReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.region_boss_level_apply_req) 11 | public class HandlerRegionBossLevelApplyReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = RegionBossLevelApplyReq.parseFrom(message); 17 | 18 | var data = GameData.getRegionBossLevelDataTable().get(req.getId()); 19 | if (data == null || !data.hasEnergy(session.getPlayer())) { 20 | return session.encodeMsg(NetMsgId.region_boss_level_apply_failed_ack); 21 | } 22 | 23 | // Set player instance id 24 | session.getPlayer().getInstanceManager().setCurInstanceId(req.getId()); 25 | 26 | // Send response 27 | return session.encodeMsg(NetMsgId.region_boss_level_apply_succeed_ack); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/GachaPkgDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.data.ResourceType.LoadPriority; 6 | import emu.nebula.util.WeightedList; 7 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 8 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 9 | import lombok.Getter; 10 | 11 | @Getter 12 | @ResourceType(name = "GachaPkg.json", loadPriority = LoadPriority.LOW) 13 | public class GachaPkgDef extends BaseDef { 14 | private int PkgId; 15 | private int GoodsId; 16 | private int Weight; 17 | 18 | private static final Int2ObjectMap> packages = new Int2ObjectOpenHashMap<>(); 19 | 20 | @Override @Deprecated 21 | public int getId() { 22 | return PkgId; 23 | } 24 | 25 | public static WeightedList getPackageById(int packageId) { 26 | return packages.get(packageId); 27 | } 28 | 29 | @Override 30 | public void onLoad() { 31 | // Add to package 32 | var list = packages.computeIfAbsent(this.getPkgId(), i -> new WeightedList()); 33 | list.add(this.getWeight(), this.getGoodsId()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/game/tower/cases/CaseType.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.game.tower.cases; 2 | 3 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 4 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 5 | import lombok.Getter; 6 | 7 | public enum CaseType { 8 | Battle (1), 9 | OpenDoor (2), 10 | PotentialSelect (3), 11 | FateCardSelect (4), 12 | NoteSelect (5), 13 | NpcEvent (6), 14 | SelectSpecialPotential (7), 15 | RecoveryHP (8), 16 | NpcRecoveryHP (9), 17 | Hawker (10), 18 | StrengthenMachine (11), 19 | DoorDanger (12), 20 | SyncHP (13); 21 | 22 | @Getter 23 | private final int value; 24 | private final static Int2ObjectMap map = new Int2ObjectOpenHashMap<>(); 25 | 26 | static { 27 | for (CaseType type : CaseType.values()) { 28 | map.put(type.getValue(), type); 29 | } 30 | } 31 | 32 | private CaseType(int value) { 33 | this.value = value; 34 | } 35 | 36 | public static CaseType getByValue(int value) { 37 | return map.get(value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/CharGemAttrValueDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.GameData; 5 | import emu.nebula.data.ResourceType; 6 | import emu.nebula.data.ResourceType.LoadPriority; 7 | import lombok.Getter; 8 | 9 | @Getter 10 | @ResourceType(name = "CharGemAttrValue.json", loadPriority = LoadPriority.LOW) 11 | public class CharGemAttrValueDef extends BaseDef { 12 | private int Id; 13 | private int TypeId; 14 | private int AttrType; 15 | private int Rarity; 16 | 17 | @Override 18 | public int getId() { 19 | return Id; 20 | } 21 | 22 | @Override 23 | public void onLoad() { 24 | // Cache attribute values into attribute group defs 25 | // Honestly a horrible/inefficient way of doing this 26 | for (var data : GameData.getCharGemAttrGroupDataTable()) { 27 | for (var type : data.getAttributeTypes()) { 28 | // Skip if type id doesnt match 29 | if (type.getId() != this.getTypeId()) { 30 | continue; 31 | } 32 | 33 | // Add 34 | type.addValue(this); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendAllAgreeReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendAllAgree.FriendAllAgreeResp; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.friend_all_agree_req) 10 | public class HandlerFriendAllAgreeReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Agree to all friend requests 15 | var results = session.getPlayer().getFriendList().acceptAll(); 16 | 17 | // Scuffed way of getting friend data 18 | var proto = session.getPlayer().getFriendList().getCachedProto(); 19 | 20 | // Build response 21 | var rsp = FriendAllAgreeResp.newInstance(); 22 | 23 | for (var f : results) { 24 | rsp.addFriends(f.getFriendProto()); 25 | } 26 | 27 | for (var i : proto.getInvites()) { 28 | rsp.addInvites(i); 29 | } 30 | 31 | // Encode and send 32 | return session.encodeMsg(NetMsgId.friend_all_agree_succeed_ack, rsp); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMailPinReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MailPin.MailPinRequest; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.game.mail.GameMail; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.mail_pin_req) 11 | public class HandlerMailPinReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = MailPinRequest.parseFrom(message); 17 | 18 | // Pin mail 19 | GameMail mail = session.getPlayer().getMailbox().pinMail(req.getId(), req.getFlag(), req.hasPin()); 20 | 21 | // Sanity check 22 | if (mail == null) { 23 | return session.encodeMsg(NetMsgId.mail_pin_failed_ack); 24 | } 25 | 26 | // Build response 27 | var rsp = MailPinRequest.newInstance() 28 | .setId(mail.getId()) 29 | .setFlag(mail.getFlag()) 30 | .setPin(mail.isPin()); 31 | 32 | return session.encodeMsg(NetMsgId.mail_pin_succeed_ack, rsp); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/routes/MetaPatchListHandler.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.routes; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import emu.nebula.server.HttpServer; 6 | import emu.nebula.util.AeadHelper; 7 | import emu.nebula.util.Utils; 8 | import io.javalin.http.ContentType; 9 | import io.javalin.http.Context; 10 | import io.javalin.http.Handler; 11 | import lombok.AccessLevel; 12 | import lombok.Getter; 13 | 14 | @Getter(AccessLevel.PRIVATE) 15 | public class MetaPatchListHandler implements Handler { 16 | private HttpServer server; 17 | 18 | public MetaPatchListHandler(HttpServer server) { 19 | this.server = server; 20 | } 21 | 22 | @Override 23 | public void handle(@NotNull Context ctx) throws Exception { 24 | // Get diff 25 | var diffBytes = this.getServer().getDiff(); 26 | 27 | // Sanity check 28 | if (diffBytes == null) { 29 | ctx.contentType(ContentType.APPLICATION_OCTET_STREAM); 30 | ctx.result(Utils.EMPTY_BYTE_ARRAY); 31 | return; 32 | } 33 | 34 | // Encrypt patch list 35 | ctx.contentType(ContentType.APPLICATION_OCTET_STREAM); 36 | ctx.result(AeadHelper.encryptCBC(diffBytes)); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/util/ints/CustomIntArray.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.util.ints; 2 | 3 | import it.unimi.dsi.fastutil.ints.IntArrayList; 4 | 5 | public class CustomIntArray extends IntArrayList { 6 | private static final long serialVersionUID = -3887905394107667439L; 7 | 8 | public CustomIntArray() { 9 | super(); 10 | } 11 | 12 | public void add(int index, int value) { 13 | while (index > this.size()) { 14 | super.add(0); 15 | } 16 | 17 | super.add(index, value); 18 | } 19 | 20 | @Override 21 | public boolean add(int value) { 22 | for (int i = 0; i < this.size(); i++) { 23 | if (this.getInt(i) == 0) { 24 | this.set(i, value); 25 | return true; 26 | } 27 | } 28 | 29 | return super.add(value); 30 | } 31 | 32 | /** 33 | * Returns the amount of non-zero values in this array 34 | */ 35 | public int getValueCount() { 36 | int realSize = 0; 37 | 38 | for (int i = 0; i < super.size(); i++) { 39 | if (this.getInt(i) != 0) { 40 | realSize++; 41 | } 42 | } 43 | 44 | return realSize; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/MallShopDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | import emu.nebula.data.BaseDef; 6 | import emu.nebula.data.ResourceType; 7 | import emu.nebula.game.inventory.ItemParamMap; 8 | import emu.nebula.game.player.Player; 9 | import lombok.Getter; 10 | 11 | @Getter 12 | @ResourceType(name = "MallShop.json") 13 | public class MallShopDef extends BaseDef { 14 | @SerializedName("Id") 15 | private String IdString; 16 | private int Stock; 17 | 18 | private int ExchangeItemId; 19 | private int ExchangeItemQty; 20 | 21 | private int ItemId; 22 | private int ItemQty; 23 | 24 | private transient ItemParamMap products; 25 | 26 | @Override 27 | public int getId() { 28 | return IdString.hashCode(); 29 | } 30 | 31 | public int getStock(Player player) { 32 | return Math.max(this.getStock() - player.getInventory().getMallBuyCount().get(this.getIdString()), 0); 33 | } 34 | 35 | @Override 36 | public void onLoad() { 37 | this.products = new ItemParamMap(); 38 | 39 | if (this.ItemId > 0) { 40 | this.products.add(this.ItemId, this.ItemQty); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/DropPkgDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.util.Utils; 6 | import it.unimi.dsi.fastutil.ints.Int2ObjectMap; 7 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; 8 | import it.unimi.dsi.fastutil.ints.IntArrayList; 9 | import it.unimi.dsi.fastutil.ints.IntList; 10 | import lombok.Getter; 11 | 12 | @Getter 13 | @ResourceType(name = "DropPkg.json") 14 | public class DropPkgDef extends BaseDef { 15 | private int PkgId; 16 | private int ItemId; 17 | 18 | private static Int2ObjectMap PACKAGES = new Int2ObjectOpenHashMap<>(); 19 | 20 | @Override 21 | public int getId() { 22 | return PkgId; 23 | } 24 | 25 | @Override 26 | public void onLoad() { 27 | var packageList = PACKAGES.computeIfAbsent(this.PkgId, i -> new IntArrayList()); 28 | packageList.add(this.ItemId); 29 | } 30 | 31 | public static int getRandomDrop(int packageId) { 32 | var packageList = PACKAGES.get(packageId); 33 | 34 | if (packageList == null) { 35 | return 0; 36 | } 37 | 38 | return Utils.randomElement(packageList); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendAddAgreeReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendAddAgree.FriendAddAgreeReq; 6 | import emu.nebula.proto.FriendAddAgree.FriendAddAgreeResp; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.friend_add_agree_req) 11 | public class HandlerFriendAddAgreeReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = FriendAddAgreeReq.parseFrom(message); 17 | 18 | // Handle friend request 19 | var target = session.getPlayer().getFriendList().handleFriendRequest((int) req.getUId(), true); 20 | 21 | if (target == null) { 22 | return session.encodeMsg(NetMsgId.friend_add_agree_failed_ack); 23 | } 24 | 25 | // Build response 26 | var rsp = FriendAddAgreeResp.newInstance() 27 | .setFriend(target.getFriendProto()); 28 | 29 | // Encode and send 30 | return session.encodeMsg(NetMsgId.friend_add_agree_succeed_ack, rsp); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/command/commands/RemoteKeyCommand.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.command.commands; 2 | 3 | import emu.nebula.Nebula; 4 | import emu.nebula.command.Command; 5 | import emu.nebula.command.CommandArgs; 6 | import emu.nebula.command.CommandHandler; 7 | 8 | import java.util.Random; 9 | 10 | @Command(label = "remote", permission = "player.remote", requireTarget = true, desc = "!remote = Creates a player token for remote api usage") 11 | public class RemoteKeyCommand implements CommandHandler { 12 | private final String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 13 | 14 | @Override 15 | public String execute(CommandArgs args) { 16 | if (Nebula.getConfig().getRemoteCommand().useRemoteServices) { 17 | StringBuilder sb = new StringBuilder(); 18 | Random random = new Random(); 19 | 20 | for (int i = 0; i < 8; i++) { 21 | int index = random.nextInt(characters.length()); 22 | sb.append(characters.charAt(index)); 23 | } 24 | 25 | args.getTarget().setRemoteToken(sb.toString()); 26 | return "Key Generated: " + sb.toString(); 27 | } else { 28 | args.getTarget().setRemoteToken(null); 29 | return "Remote Command Disabled on Server"; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerCharGemUsePresetReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.CharGemUsePreset.CharGemUsePresetReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.char_gem_use_preset_req) 10 | public class HandlerCharGemUsePresetReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | // Parse request 15 | var req = CharGemUsePresetReq.parseFrom(message); 16 | 17 | // Get character 18 | var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId()); 19 | 20 | if (character == null) { 21 | return session.encodeMsg(NetMsgId.char_gem_use_preset_failed_ack); 22 | } 23 | 24 | // Use preset 25 | boolean success = character.setCurrentGemPreset(req.getPresetId()); 26 | 27 | if (success == false) { 28 | return session.encodeMsg(NetMsgId.char_gem_use_preset_failed_ack); 29 | } 30 | 31 | // Encode and send 32 | return session.encodeMsg(NetMsgId.char_gem_use_preset_succeed_ack); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerCharSkillUpgradeReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.CharSkillUpgrade.CharSkillUpgradeReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.net.GameSession; 8 | 9 | @HandlerId(NetMsgId.char_skill_upgrade_req) 10 | public class HandlerCharSkillUpgradeReq extends NetHandler { 11 | 12 | @Override 13 | public byte[] handle(GameSession session, byte[] message) throws Exception { 14 | var req = CharSkillUpgradeReq.parseFrom(message); 15 | 16 | // Get character 17 | var character = session.getPlayer().getCharacters().getCharacterById(req.getCharId()); 18 | 19 | if (character == null) { 20 | return session.encodeMsg(NetMsgId.char_skill_upgrade_failed_ack); 21 | } 22 | 23 | // Advance character 24 | int index = req.getIndex() - 1; // Lua indexes start at 1 25 | var change = character.upgradeSkill(index); 26 | 27 | if (change == null) { 28 | return session.encodeMsg(NetMsgId.char_skill_upgrade_failed_ack); 29 | } 30 | 31 | return session.encodeMsg(NetMsgId.char_skill_upgrade_succeed_ack, change.toProto()); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerFriendUidSearchReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.FriendUidSearch.FriendUIdSearchReq; 6 | import emu.nebula.proto.FriendUidSearch.FriendUIdSearchResp; 7 | import emu.nebula.net.HandlerId; 8 | import emu.nebula.Nebula; 9 | import emu.nebula.net.GameSession; 10 | 11 | @HandlerId(NetMsgId.friend_uid_search_req) 12 | public class HandlerFriendUidSearchReq extends NetHandler { 13 | 14 | @Override 15 | public byte[] handle(GameSession session, byte[] message) throws Exception { 16 | // Parse request 17 | var req = FriendUIdSearchReq.parseFrom(message); 18 | int uid = (int) req.getId(); 19 | 20 | // Get target player 21 | var target = Nebula.getGameContext().getPlayerModule().getPlayer(uid); 22 | 23 | if (target == null) { 24 | return session.encodeMsg(NetMsgId.friend_uid_search_failed_ack); 25 | } 26 | 27 | // Build response 28 | var rsp = FriendUIdSearchResp.newInstance() 29 | .setFriend(target.getFriendProto()); 30 | 31 | // Encode and send 32 | return session.encodeMsg(NetMsgId.friend_uid_search_succeed_ack, rsp); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/server/handlers/HandlerMallShopOrderReq.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.server.handlers; 2 | 3 | import emu.nebula.net.NetHandler; 4 | import emu.nebula.net.NetMsgId; 5 | import emu.nebula.proto.MallShopOrder.MallShopOrderReq; 6 | import emu.nebula.net.HandlerId; 7 | import emu.nebula.data.GameData; 8 | import emu.nebula.net.GameSession; 9 | 10 | @HandlerId(NetMsgId.mall_shop_order_req ) 11 | public class HandlerMallShopOrderReq extends NetHandler { 12 | 13 | @Override 14 | public byte[] handle(GameSession session, byte[] message) throws Exception { 15 | // Parse request 16 | var req = MallShopOrderReq.parseFrom(message); 17 | 18 | // Get package data 19 | var data = GameData.getMallShopDataTable().get(req.getId().hashCode()); 20 | if (data == null) { 21 | return session.encodeMsg(NetMsgId.mall_shop_order_failed_ack); 22 | } 23 | 24 | // Buy items 25 | var change = session.getPlayer().getInventory().buyMallItem(data, req.getQty()); 26 | 27 | if (change == null) { 28 | return session.encodeMsg(NetMsgId.mall_shop_order_failed_ack); 29 | } 30 | 31 | // Encode and send 32 | return session.encodeMsg(NetMsgId.mall_shop_order_succeed_ack, change.toProto()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/emu/nebula/data/resources/BattlePassRewardDef.java: -------------------------------------------------------------------------------- 1 | package emu.nebula.data.resources; 2 | 3 | import emu.nebula.data.BaseDef; 4 | import emu.nebula.data.ResourceType; 5 | import emu.nebula.game.inventory.ItemParamMap; 6 | import lombok.Getter; 7 | 8 | @Getter 9 | @ResourceType(name = "BattlePassReward.json") 10 | public class BattlePassRewardDef extends BaseDef { 11 | private int ID; 12 | private int Level; 13 | 14 | private int Tid1; 15 | private int Qty1; 16 | private int Tid2; 17 | private int Qty2; 18 | private int Tid3; 19 | private int Qty3; 20 | 21 | private transient ItemParamMap basicRewards; 22 | private transient ItemParamMap premiumRewards; 23 | 24 | @Override 25 | public int getId() { 26 | return (ID << 16) + Level; 27 | } 28 | 29 | @Override 30 | public void onLoad() { 31 | this.basicRewards = new ItemParamMap(); 32 | this.premiumRewards = new ItemParamMap(); 33 | 34 | if (this.Tid1 > 0) { 35 | this.basicRewards.add(this.Tid1, this.Qty1); 36 | } 37 | 38 | if (this.Tid2 > 0) { 39 | this.premiumRewards.add(this.Tid2, this.Qty2); 40 | } 41 | if (this.Tid3 > 0) { 42 | this.premiumRewards.add(this.Tid3, this.Qty3); 43 | } 44 | } 45 | } 46 | --------------------------------------------------------------------------------