refactor: move Minecraft.Client into app

This commit is contained in:
MatthewBeshay
2026-04-02 16:09:32 +11:00
parent e5a859f8a7
commit 11f9bd6046
784 changed files with 2598 additions and 2604 deletions
+135
View File
@@ -0,0 +1,135 @@
#pragma once
// 4J Stu - For non-splitscreen menus, default to this screen
#define DEFAULT_XUI_MENU_USER 0
#define MULTITHREAD_ENABLE
#define MAX_CAPENAME_SIZE 32
#define MAX_BANNERNAME_SIZE 32
#define MAX_TMSFILENAME_SIZE 40
#define MAX_TYPE_SIZE 32
#define MAX_EXTENSION_TYPES 3
#define MAX_LOCAL_PLAYERS 4
// 4J Stu - Required for sentient reporting of whether the volume level has been
// changed or not
#define DEFAULT_VOLUME_LEVEL 100
#define GAME_HOST_OPTION_BITMASK_DIFFICULTY 0x00000003 // 0 - 3
#define GAME_HOST_OPTION_BITMASK_FRIENDSOFFRIENDS 0x00000004
#define GAME_HOST_OPTION_BITMASK_GAMERTAGS 0x00000008
#define GAME_HOST_OPTION_BITMASK_GAMETYPE 0x00000030
#define GAME_HOST_OPTION_BITMASK_LEVELTYPE 0x00000040
#define GAME_HOST_OPTION_BITMASK_STRUCTURES 0x00000080
#define GAME_HOST_OPTION_BITMASK_BONUSCHEST 0x00000100
#define GAME_HOST_OPTION_BITMASK_BEENINCREATIVE 0x00000200
#define GAME_HOST_OPTION_BITMASK_PVP 0x00000400
#define GAME_HOST_OPTION_BITMASK_TRUSTPLAYERS 0x00000800
#define GAME_HOST_OPTION_BITMASK_TNT 0x00001000
#define GAME_HOST_OPTION_BITMASK_FIRESPREADS 0x00002000
#define GAME_HOST_OPTION_BITMASK_HOSTFLY 0x00004000
#define GAME_HOST_OPTION_BITMASK_HOSTHUNGER 0x00008000
#define GAME_HOST_OPTION_BITMASK_HOSTINVISIBLE 0x00010000
#define GAME_HOST_OPTION_BITMASK_BEDROCKFOG 0x00020000
#define GAME_HOST_OPTION_BITMASK_DISABLESAVE 0x00040000
#define GAME_HOST_OPTION_BITMASK_NOTOWNER 0x00080000
#define GAME_HOST_OPTION_BITMASK_WORLDSIZE \
0x00700000 // 3 bits, 5 values (unset(0), classic(1), small(2), medium(3),
// large(4))
#define GAME_HOST_OPTION_BITMASK_MOBGRIEFING 0x00800000
#define GAME_HOST_OPTION_BITMASK_KEEPINVENTORY 0x01000000
#define GAME_HOST_OPTION_BITMASK_DOMOBSPAWNING 0x02000000
#define GAME_HOST_OPTION_BITMASK_DOMOBLOOT 0x04000000
#define GAME_HOST_OPTION_BITMASK_DOTILEDROPS 0x08000000
#define GAME_HOST_OPTION_BITMASK_NATURALREGEN 0x10000000
#define GAME_HOST_OPTION_BITMASK_DODAYLIGHTCYCLE 0x20000000
#define GAME_HOST_OPTION_BITMASK_ALL 0xFFFFFFFF
#define GAME_HOST_OPTION_BITMASK_WORLDSIZE_BITSHIFT 20
enum EGameHostOptionWorldSize {
e_worldSize_Unknown = 0,
e_worldSize_Classic,
e_worldSize_Small,
e_worldSize_Medium,
e_worldSize_Large
};
#define PROFILE_VERSION_8 10
#define PROFILE_VERSION_9 11
#define PROFILE_VERSION_10 12
// 4J-JEV: New Statistics and Achievements for 'NexGen' platforms.
#define PROFILE_VERSION_11 13
// Java 1.6.4
#define PROFILE_VERSION_12 14
#define PROFILE_VERSION_CURRENT PROFILE_VERSION_12
#define MAX_FAVORITE_SKINS \
10 // these are stored in the profile data so keep it small
// defines for game settings - uiBitmaskValues
#define GAMESETTING_CLOUDS 0x00000001
#define GAMESETTING_ONLINE 0x00000002
#define GAMESETTING_INVITEONLY 0x00000004
#define GAMESETTING_FRIENDSOFFRIENDS 0x00000008
#define GAMESETTING_DISPLAYUPDATEMSG 0x00000030
#define GAMESETTING_BEDROCKFOG 0x00000040
#define GAMESETTING_DISPLAYHUD 0x00000080
#define GAMESETTING_DISPLAYHAND 0x00000100
#define GAMESETTING_CUSTOMSKINANIM 0x00000200
#define GAMESETTING_DEATHMESSAGES 0x00000400
#define GAMESETTING_UISIZE 0x00001800
#define GAMESETTING_UISIZE_SPLITSCREEN 0x00006000
#define GAMESETTING_ANIMATEDCHARACTER 0x00008000
#define GAMESETTING_PS3EULAREAD 0x00010000
#define GAMESETTING_PSVITANETWORKMODEADHOC 0x00020000
// defines for languages
#define MINECRAFT_LANGUAGE_DEFAULT 0x00
#define MINECRAFT_LANGUAGE_ENGLISH 0x01
#define MINECRAFT_LANGUAGE_JAPANESE 0x02
#define MINECRAFT_LANGUAGE_GERMAN 0x03
#define MINECRAFT_LANGUAGE_FRENCH 0x04
#define MINECRAFT_LANGUAGE_SPANISH 0x05
#define MINECRAFT_LANGUAGE_ITALIAN 0x06
#define MINECRAFT_LANGUAGE_KOREAN 0x07
#define MINECRAFT_LANGUAGE_TCHINESE 0x08
#define MINECRAFT_LANGUAGE_PORTUGUESE 0x09
#define MINECRAFT_LANGUAGE_BRAZILIAN 0x0A
#define MINECRAFT_LANGUAGE_RUSSIAN 0x0B
#define MINECRAFT_LANGUAGE_DUTCH 0x0C
#define MINECRAFT_LANGUAGE_FINISH 0x0D
#define MINECRAFT_LANGUAGE_SWEDISH 0x0E
#define MINECRAFT_LANGUAGE_DANISH 0x0F
#define MINECRAFT_LANGUAGE_NORWEGIAN 0x10
#define MINECRAFT_LANGUAGE_POLISH 0x11
#define MINECRAFT_LANGUAGE_TURKISH 0x12
#define MINECRAFT_LANGUAGE_LATINAMERICANSPANISH 0x13
#define MINECRAFT_LANGUAGE_GREEK 0x14
/* Match these
const int XC_LANGUAGE_ENGLISH =1; const int XC_LANGUAGE_JAPANESE
=2; const int XC_LANGUAGE_GERMAN
=3; const int XC_LANGUAGE_FRENCH
=4; const int XC_LANGUAGE_SPANISH
=5; const int XC_LANGUAGE_ITALIAN
=6; const int XC_LANGUAGE_KOREAN
=7; const int XC_LANGUAGE_TCHINESE
=8; const int XC_LANGUAGE_PORTUGUESE =9; const int XC_LANGUAGE_BRAZILIAN
=10; const int XC_LANGUAGE_RUSSIAN
=11; const int XC_LANGUAGE_DUTCH
=12; const int XC_LANGUAGE_FINISH
=13; const int XC_LANGUAGE_SWEDISH
=14; const int XC_LANGUAGE_DANISH
=15; const int XC_LANGUAGE_NORWEGIAN =16; const int XC_LANGUAGE_POLISH
=17; const int XC_LANGUAGE_TURKISH
=18; const int XC_LANGUAGE_LATINAMERICANSPANISH =19;
const int XC_LANGUAGE_GREEK =20;
*/
+706
View File
@@ -0,0 +1,706 @@
#pragma once
enum eFileExtensionType {
eFileExtensionType_PNG = 0,
eFileExtensionType_INF,
eFileExtensionType_DAT,
};
enum eTMSFileType {
eTMSFileType_MinecraftStore = 0,
eTMSFileType_TexturePack,
eTMSFileType_All
};
enum eTPDFileType {
eTPDFileType_Loc = 0,
eTPDFileType_Icon,
// eTPDFileType_Banner,
eTPDFileType_Comparison,
};
enum eFont {
eFont_European = 0,
eFont_Korean,
eFont_Japanese,
eFont_Chinese,
eFont_None, // to fallback to nothing
};
enum eXuiAction {
eAppAction_Idle = 0,
eAppAction_SaveGame,
eAppAction_SaveGameCapturedThumbnail,
eAppAction_ExitWorld,
eAppAction_ExitWorldCapturedThumbnail,
eAppAction_ExitWorldTrial,
// eAppAction_ExitGameFatalLoadError,
eAppAction_Respawn,
eAppAction_WaitForRespawnComplete,
eAppAction_PrimaryPlayerSignedOut,
eAppAction_PrimaryPlayerSignedOutReturned,
eAppAction_PrimaryPlayerSignedOutReturned_Menus,
eAppAction_ExitPlayer, // secondary player
eAppAction_ExitPlayerPreLogin,
eAppAction_TrialOver,
eAppAction_ExitTrial,
eAppAction_WaitForDimensionChangeComplete,
// eAppAction_SocialPost,
// eAppAction_SocialPostScreenshot,
eAppAction_EthernetDisconnected,
eAppAction_EthernetDisconnectedReturned,
eAppAction_EthernetDisconnectedReturned_Menus,
eAppAction_ExitAndJoinFromInvite,
eAppAction_DashboardTrialJoinFromInvite,
eAppAction_ExitAndJoinFromInviteConfirmed,
eAppAction_JoinFromInvite,
eAppAction_ChangeSessionType,
eAppAction_SetDefaultOptions,
eAppAction_LocalPlayerJoined,
eAppAction_RemoteServerSave,
eAppAction_WaitRemoteServerSaveComplete,
eAppAction_FailedToJoinNoPrivileges,
eAppAction_AutosaveSaveGame,
eAppAction_AutosaveSaveGameCapturedThumbnail,
eAppAction_ProfileReadError,
eAppAction_DisplayLavaMessage,
eAppAction_BanLevel,
eAppAction_LevelInBanLevelList,
eAppAction_ReloadTexturePack,
eAppAction_ReloadFont,
eAppAction_TexturePackRequired, // when the user has joined from invite,
// but doesn't have the texture pack
eAppAction_DebugText,
};
enum eTMSAction {
eTMSAction_Idle = 0,
eTMSAction_TMS_RetrieveFiles_Complete,
eTMSAction_TMSPP_RetrieveFiles_CreateLoad_SignInReturned,
eTMSAction_TMSPP_RetrieveFiles_RunPlayGame,
eTMSAction_TMSPP_RetrieveFiles_HelpAndOptions,
eTMSAction_TMSPP_RetrieveFiles_DLCMain,
eTMSAction_TMSPP_GlobalFileList,
eTMSAction_TMSPP_GlobalFileList_Waiting,
// eTMSAction_TMSPP_ConfigFile,
// eTMSAction_TMSPP_ConfigFile_Waiting,
eTMSAction_TMSPP_UserFileList,
eTMSAction_TMSPP_UserFileList_Waiting,
eTMSAction_TMSPP_XUIDSFile,
eTMSAction_TMSPP_XUIDSFile_Waiting,
eTMSAction_TMSPP_DLCFile,
eTMSAction_TMSPP_DLCFile_Waiting,
eTMSAction_TMSPP_BannedListFile,
eTMSAction_TMSPP_BannedListFile_Waiting,
eTMSAction_TMSPP_RetrieveFiles_Complete,
eTMSAction_TMSPP_DLCFileOnly,
eTMSAction_TMSPP_RetrieveUserFilelist_DLCFileOnly,
};
// The server runs on its own thread, so we need to call its actions there
// rather than where all other Xui actions are performed In general these are
// debugging options
enum eXuiServerAction {
eXuiServerAction_Idle = 0,
eXuiServerAction_DropItem, // Debug
eXuiServerAction_SaveGame,
eXuiServerAction_AutoSaveGame,
eXuiServerAction_SpawnMob, // Debug
eXuiServerAction_PauseServer,
eXuiServerAction_ToggleRain, // Debug
eXuiServerAction_ToggleThunder, // Debug
eXuiServerAction_ServerSettingChanged_Gamertags,
eXuiServerAction_ServerSettingChanged_Difficulty,
eXuiServerAction_ExportSchematic, // Debug
eXuiServerAction_ServerSettingChanged_BedrockFog,
eXuiServerAction_SetCameraLocation, // Debug
};
enum eGameSetting {
eGameSetting_MusicVolume = 0,
eGameSetting_SoundFXVolume,
eGameSetting_Gamma,
eGameSetting_Difficulty,
eGameSetting_Sensitivity_InGame,
eGameSetting_Sensitivity_InMenu,
eGameSetting_ViewBob,
eGameSetting_ControlScheme,
eGameSetting_ControlInvertLook,
eGameSetting_ControlSouthPaw,
eGameSetting_SplitScreenVertical,
eGameSetting_GamertagsVisible,
// Interim TU 1.6.6
eGameSetting_Autosave,
eGameSetting_DisplaySplitscreenGamertags,
eGameSetting_Hints,
eGameSetting_InterfaceOpacity,
eGameSetting_Tooltips,
// TU5
eGameSetting_Clouds,
eGameSetting_Online,
eGameSetting_InviteOnly,
eGameSetting_FriendsOfFriends,
eGameSetting_DisplayUpdateMessage,
// TU6
eGameSetting_BedrockFog,
eGameSetting_DisplayHUD,
eGameSetting_DisplayHand,
// TU7
eGameSetting_CustomSkinAnim,
// TU9
eGameSetting_DeathMessages,
eGameSetting_UISize,
eGameSetting_UISizeSplitscreen,
eGameSetting_AnimatedCharacter,
// PS3
eGameSetting_PS3_EULA_Read,
// PSVita
eGameSetting_PSVita_NetworkModeAdhoc,
};
enum eGameMode { eMode_Singleplayer, eMode_Multiplayer };
enum eMinecraftColour {
eMinecraftColour_NOT_SET,
eMinecraftColour_Foliage_Evergreen,
eMinecraftColour_Foliage_Birch,
eMinecraftColour_Foliage_Default,
eMinecraftColour_Foliage_Common,
eMinecraftColour_Foliage_Ocean,
eMinecraftColour_Foliage_Plains,
eMinecraftColour_Foliage_Desert,
eMinecraftColour_Foliage_ExtremeHills,
eMinecraftColour_Foliage_Forest,
eMinecraftColour_Foliage_Taiga,
eMinecraftColour_Foliage_Swampland,
eMinecraftColour_Foliage_River,
eMinecraftColour_Foliage_Hell,
eMinecraftColour_Foliage_Sky,
eMinecraftColour_Foliage_FrozenOcean,
eMinecraftColour_Foliage_FrozenRiver,
eMinecraftColour_Foliage_IcePlains,
eMinecraftColour_Foliage_IceMountains,
eMinecraftColour_Foliage_MushroomIsland,
eMinecraftColour_Foliage_MushroomIslandShore,
eMinecraftColour_Foliage_Beach,
eMinecraftColour_Foliage_DesertHills,
eMinecraftColour_Foliage_ForestHills,
eMinecraftColour_Foliage_TaigaHills,
eMinecraftColour_Foliage_ExtremeHillsEdge,
eMinecraftColour_Foliage_Jungle,
eMinecraftColour_Foliage_JungleHills,
eMinecraftColour_Grass_Common,
eMinecraftColour_Grass_Ocean,
eMinecraftColour_Grass_Plains,
eMinecraftColour_Grass_Desert,
eMinecraftColour_Grass_ExtremeHills,
eMinecraftColour_Grass_Forest,
eMinecraftColour_Grass_Taiga,
eMinecraftColour_Grass_Swampland,
eMinecraftColour_Grass_River,
eMinecraftColour_Grass_Hell,
eMinecraftColour_Grass_Sky,
eMinecraftColour_Grass_FrozenOcean,
eMinecraftColour_Grass_FrozenRiver,
eMinecraftColour_Grass_IcePlains,
eMinecraftColour_Grass_IceMountains,
eMinecraftColour_Grass_MushroomIsland,
eMinecraftColour_Grass_MushroomIslandShore,
eMinecraftColour_Grass_Beach,
eMinecraftColour_Grass_DesertHills,
eMinecraftColour_Grass_ForestHills,
eMinecraftColour_Grass_TaigaHills,
eMinecraftColour_Grass_ExtremeHillsEdge,
eMinecraftColour_Grass_Jungle,
eMinecraftColour_Grass_JungleHills,
eMinecraftColour_Water_Ocean,
eMinecraftColour_Water_Plains,
eMinecraftColour_Water_Desert,
eMinecraftColour_Water_ExtremeHills,
eMinecraftColour_Water_Forest,
eMinecraftColour_Water_Taiga,
eMinecraftColour_Water_Swampland,
eMinecraftColour_Water_River,
eMinecraftColour_Water_Hell,
eMinecraftColour_Water_Sky,
eMinecraftColour_Water_FrozenOcean,
eMinecraftColour_Water_FrozenRiver,
eMinecraftColour_Water_IcePlains,
eMinecraftColour_Water_IceMountains,
eMinecraftColour_Water_MushroomIsland,
eMinecraftColour_Water_MushroomIslandShore,
eMinecraftColour_Water_Beach,
eMinecraftColour_Water_DesertHills,
eMinecraftColour_Water_ForestHills,
eMinecraftColour_Water_TaigaHills,
eMinecraftColour_Water_ExtremeHillsEdge,
eMinecraftColour_Water_Jungle,
eMinecraftColour_Water_JungleHills,
eMinecraftColour_Sky_Ocean,
eMinecraftColour_Sky_Plains,
eMinecraftColour_Sky_Desert,
eMinecraftColour_Sky_ExtremeHills,
eMinecraftColour_Sky_Forest,
eMinecraftColour_Sky_Taiga,
eMinecraftColour_Sky_Swampland,
eMinecraftColour_Sky_River,
eMinecraftColour_Sky_Hell,
eMinecraftColour_Sky_Sky,
eMinecraftColour_Sky_FrozenOcean,
eMinecraftColour_Sky_FrozenRiver,
eMinecraftColour_Sky_IcePlains,
eMinecraftColour_Sky_IceMountains,
eMinecraftColour_Sky_MushroomIsland,
eMinecraftColour_Sky_MushroomIslandShore,
eMinecraftColour_Sky_Beach,
eMinecraftColour_Sky_DesertHills,
eMinecraftColour_Sky_ForestHills,
eMinecraftColour_Sky_TaigaHills,
eMinecraftColour_Sky_ExtremeHillsEdge,
eMinecraftColour_Sky_Jungle,
eMinecraftColour_Sky_JungleHills,
eMinecraftColour_Tile_RedstoneDust,
eMinecraftColour_Tile_RedstoneDustUnlit,
eMinecraftColour_Tile_RedstoneDustLitMin,
eMinecraftColour_Tile_RedstoneDustLitMax,
eMinecraftColour_Tile_StemMin,
eMinecraftColour_Tile_StemMax,
eMinecraftColour_Tile_WaterLily,
eMinecraftColour_Sky_Dawn_Dark,
eMinecraftColour_Sky_Dawn_Bright,
eMinecraftColour_Material_None,
eMinecraftColour_Material_Grass,
eMinecraftColour_Material_Sand,
eMinecraftColour_Material_Cloth,
eMinecraftColour_Material_Fire,
eMinecraftColour_Material_Ice,
eMinecraftColour_Material_Metal,
eMinecraftColour_Material_Plant,
eMinecraftColour_Material_Snow,
eMinecraftColour_Material_Clay,
eMinecraftColour_Material_Dirt,
eMinecraftColour_Material_Stone,
eMinecraftColour_Material_Water,
eMinecraftColour_Material_Wood,
eMinecraftColour_Material_Emerald,
eMinecraftColour_Particle_Note_00,
eMinecraftColour_Particle_Note_01,
eMinecraftColour_Particle_Note_02,
eMinecraftColour_Particle_Note_03,
eMinecraftColour_Particle_Note_04,
eMinecraftColour_Particle_Note_05,
eMinecraftColour_Particle_Note_06,
eMinecraftColour_Particle_Note_07,
eMinecraftColour_Particle_Note_08,
eMinecraftColour_Particle_Note_09,
eMinecraftColour_Particle_Note_10,
eMinecraftColour_Particle_Note_11,
eMinecraftColour_Particle_Note_12,
eMinecraftColour_Particle_Note_13,
eMinecraftColour_Particle_Note_14,
eMinecraftColour_Particle_Note_15,
eMinecraftColour_Particle_Note_16,
eMinecraftColour_Particle_Note_17,
eMinecraftColour_Particle_Note_18,
eMinecraftColour_Particle_Note_19,
eMinecraftColour_Particle_Note_20,
eMinecraftColour_Particle_Note_21,
eMinecraftColour_Particle_Note_22,
eMinecraftColour_Particle_Note_23,
eMinecraftColour_Particle_Note_24,
eMinecraftColour_Particle_NetherPortal,
eMinecraftColour_Particle_EnderPortal,
eMinecraftColour_Particle_Smoke,
eMinecraftColour_Particle_Ender,
eMinecraftColour_Particle_Explode,
eMinecraftColour_Particle_HugeExplosion,
eMinecraftColour_Particle_DripWater,
eMinecraftColour_Particle_DripLavaStart,
eMinecraftColour_Particle_DripLavaEnd,
eMinecraftColour_Particle_EnchantmentTable,
eMinecraftColour_Particle_DragonBreathMin,
eMinecraftColour_Particle_DragonBreathMax,
eMinecraftColour_Particle_Suspend,
eMinecraftColour_Particle_CritStart,
eMinecraftColour_Particle_CritEnd,
eMinecraftColour_Effect_MovementSpeed,
eMinecraftColour_Effect_MovementSlowDown,
eMinecraftColour_Effect_DigSpeed,
eMinecraftColour_Effect_DigSlowdown,
eMinecraftColour_Effect_DamageBoost,
eMinecraftColour_Effect_Heal,
eMinecraftColour_Effect_Harm,
eMinecraftColour_Effect_Jump,
eMinecraftColour_Effect_Confusion,
eMinecraftColour_Effect_Regeneration,
eMinecraftColour_Effect_DamageResistance,
eMinecraftColour_Effect_FireResistance,
eMinecraftColour_Effect_WaterBreathing,
eMinecraftColour_Effect_Invisiblity,
eMinecraftColour_Effect_Blindness,
eMinecraftColour_Effect_NightVision,
eMinecraftColour_Effect_Hunger,
eMinecraftColour_Effect_Weakness,
eMinecraftColour_Effect_Poison,
eMinecraftColour_Effect_Wither,
eMinecraftColour_Effect_HealthBoost,
eMinecraftColour_Effect_Absoprtion,
eMinecraftColour_Effect_Saturation,
eMinecraftColour_Potion_BaseColour,
eMinecraftColour_Mob_Creeper_Colour1,
eMinecraftColour_Mob_Creeper_Colour2,
eMinecraftColour_Mob_Skeleton_Colour1,
eMinecraftColour_Mob_Skeleton_Colour2,
eMinecraftColour_Mob_Spider_Colour1,
eMinecraftColour_Mob_Spider_Colour2,
eMinecraftColour_Mob_Zombie_Colour1,
eMinecraftColour_Mob_Zombie_Colour2,
eMinecraftColour_Mob_Slime_Colour1,
eMinecraftColour_Mob_Slime_Colour2,
eMinecraftColour_Mob_Ghast_Colour1,
eMinecraftColour_Mob_Ghast_Colour2,
eMinecraftColour_Mob_PigZombie_Colour1,
eMinecraftColour_Mob_PigZombie_Colour2,
eMinecraftColour_Mob_Enderman_Colour1,
eMinecraftColour_Mob_Enderman_Colour2,
eMinecraftColour_Mob_CaveSpider_Colour1,
eMinecraftColour_Mob_CaveSpider_Colour2,
eMinecraftColour_Mob_Silverfish_Colour1,
eMinecraftColour_Mob_Silverfish_Colour2,
eMinecraftColour_Mob_Blaze_Colour1,
eMinecraftColour_Mob_Blaze_Colour2,
eMinecraftColour_Mob_LavaSlime_Colour1,
eMinecraftColour_Mob_LavaSlime_Colour2,
eMinecraftColour_Mob_Pig_Colour1,
eMinecraftColour_Mob_Pig_Colour2,
eMinecraftColour_Mob_Sheep_Colour1,
eMinecraftColour_Mob_Sheep_Colour2,
eMinecraftColour_Mob_Cow_Colour1,
eMinecraftColour_Mob_Cow_Colour2,
eMinecraftColour_Mob_Chicken_Colour1,
eMinecraftColour_Mob_Chicken_Colour2,
eMinecraftColour_Mob_Squid_Colour1,
eMinecraftColour_Mob_Squid_Colour2,
eMinecraftColour_Mob_Wolf_Colour1,
eMinecraftColour_Mob_Wolf_Colour2,
eMinecraftColour_Mob_MushroomCow_Colour1,
eMinecraftColour_Mob_MushroomCow_Colour2,
eMinecraftColour_Mob_Ocelot_Colour1,
eMinecraftColour_Mob_Ocelot_Colour2,
eMinecraftColour_Mob_Villager_Colour1,
eMinecraftColour_Mob_Villager_Colour2,
eMinecraftColour_Mob_Bat_Colour1,
eMinecraftColour_Mob_Bat_Colour2,
eMinecraftColour_Mob_Witch_Colour1,
eMinecraftColour_Mob_Witch_Colour2,
eMinecraftColour_Mob_Horse_Colour1,
eMinecraftColour_Mob_Horse_Colour2,
eMinecraftColour_Armour_Default_Leather_Colour,
eMinecraftColour_Under_Water_Clear_Colour,
eMinecraftColour_Under_Lava_Clear_Colour,
eMinecraftColour_In_Cloud_Base_Colour,
eMinecraftColour_Under_Water_Fog_Colour,
eMinecraftColour_Under_Lava_Fog_Colour,
eMinecraftColour_In_Cloud_Fog_Colour,
eMinecraftColour_Default_Fog_Colour,
eMinecraftColour_Nether_Fog_Colour,
eMinecraftColour_End_Fog_Colour,
eMinecraftColour_Sign_Text,
eMinecraftColour_Map_Text,
eMinecraftColour_Leash_Light_Colour,
eMinecraftColour_Leash_Dark_Colour,
eMinecraftColour_Fire_Overlay,
eHTMLColor_0,
eHTMLColor_1,
eHTMLColor_2,
eHTMLColor_3,
eHTMLColor_4,
eHTMLColor_5,
eHTMLColor_6,
eHTMLColor_7,
eHTMLColor_8,
eHTMLColor_9,
eHTMLColor_a,
eHTMLColor_b,
eHTMLColor_c,
eHTMLColor_d,
eHTMLColor_e,
eHTMLColor_f,
eHTMLColor_0_dark,
eHTMLColor_1_dark,
eHTMLColor_2_dark,
eHTMLColor_3_dark,
eHTMLColor_4_dark,
eHTMLColor_5_dark,
eHTMLColor_6_dark,
eHTMLColor_7_dark,
eHTMLColor_8_dark,
eHTMLColor_9_dark,
eHTMLColor_a_dark,
eHTMLColor_b_dark,
eHTMLColor_c_dark,
eHTMLColor_d_dark,
eHTMLColor_e_dark,
eHTMLColor_f_dark,
eHTMLColor_T1,
eHTMLColor_T2,
eHTMLColor_T3,
eHTMLColor_Black,
eHTMLColor_White,
eTextColor_Enchant,
eTextColor_EnchantFocus,
eTextColor_EnchantDisabled,
eTextColor_RenamedItemTitle,
// eHTMLColor_0 = 0x000000, //r:0 , g: 0, b: 0, i: 0
// eHTMLColor_1 = 0x0000aa, //r:0 , g: 0, b: aa, i: 1 // blue, quite dark
// eHTMLColor_2 = 0x109e10, // Changed by request of Dave //0x00aa00, //r:0
// , g: aa, b: 0, i: 2 // green eHTMLColor_3 = 0x109e9e, // Changed by
// request of Dave //0x00aaaa, //r:0 , g: aa, b: aa, i: 3 // cyan
// eHTMLColor_4 = 0xaa0000, //r:aa , g: 0, b: 0, i: 4 // red
// eHTMLColor_5 = 0xaa00aa, //r:aa , g: 0, b: aa, i: 5 // purple
// eHTMLColor_6 = 0xffaa00, //r:ff , g: aa, b: 0, i: 6 // orange
// eHTMLColor_7 = 0xaaaaaa, //r:aa , g: aa, b: aa, i: 7 // light gray
// eHTMLColor_8 = 0x555555, //r:55 , g: 55, b: 55, i: 8 // gray
// eHTMLColor_9 = 0x5555ff, //r:55 , g: 55, b: ff, i: 9 // blue
// eHTMLColor_a = 0x55ff55, //r:55 , g: ff, b: 55, i: a // green
// eHTMLColor_b = 0x55ffff, //r:55 , g: ff, b: ff, i: b // cyan
// eHTMLColor_c = 0xff5555, //r:ff , g: 55, b: 55, i: c // red pink
// eHTMLColor_d = 0xff55ff, //r:ff , g: 55, b: ff, i: d // bright pink
// eHTMLColor_e = 0xffff55, //r:ff , g: ff, b: 55, i: e // yellow
// eHTMLColor_f = 0xffffff, //r:ff , g: ff, b: ff, i: f
// eHTMLColor_0_dark = 0x000000, //r:0 , g: 0, b: 0, i: 10
// eHTMLColor_1_dark = 0x00002a, //r:0 , g: 0, b: 2a, i: 11
// eHTMLColor_2_dark = 0x002a00, //r:0 , g: 2a, b: 0, i: 12
// eHTMLColor_3_dark = 0x002a2a, //r:0 , g: 2a, b: 2a, i: 13
// eHTMLColor_4_dark = 0x2a0000, //r:2a , g: 0, b: 0, i: 14
// eHTMLColor_5_dark = 0x2a002a, //r:2a , g: 0, b: 2a, i: 15
// eHTMLColor_6_dark = 0x2a2a00, //r:2a , g: 2a, b: 0, i: 16
// eHTMLColor_7_dark = 0x2a2a2a, //r:2a , g: 2a, b: 2a, i: 17 // dark gray
// eHTMLColor_8_dark = 0x151515, //r:15 , g: 15, b: 15, i: 18
// eHTMLColor_9_dark = 0x15153f, //r:15 , g: 15, b: 3f, i: 19
// eHTMLColor_a_dark = 0x153f15, //r:15 , g: 3f, b: 15, i: 1a
// eHTMLColor_b_dark = 0x153f3f, //r:15 , g: 3f, b: 3f, i: 1b
// eHTMLColor_c_dark = 0x3f1515, //r:3f , g: 15, b: 15, i: 1c // brown
// eHTMLColor_d_dark = 0x3f153f, //r:3f , g: 15, b: 3f, i: 1d
// eHTMLColor_e_dark = 0x3f3f15, //r:3f , g: 3f, b: 15, i: 1e
// eHTMLColor_f_dark = 0x3f3f3f, //r:3f , g: 3f, b: 3f, i: 1f
eMinecraftColour_COUNT,
};
enum eDLCContentType {
e_DLC_SkinPack = 0,
e_DLC_TexturePacks,
e_DLC_MashupPacks,
e_DLC_Themes,
e_DLC_AvatarItems,
e_DLC_Gamerpics,
e_DLC_MAX_MinecraftStore,
e_DLC_TexturePackData, // for the icon, banner and text
e_DLC_MAX,
e_DLC_NotDefined,
};
enum eDLCMarketplaceType {
e_Marketplace_Content = 0, // skins, texture packs and mashup packs
e_Marketplace_Themes,
e_Marketplace_AvatarItems,
e_Marketplace_Gamerpics,
e_Marketplace_MAX,
e_Marketplace_NotDefined,
};
enum eDLCContentState {
e_DLC_ContentState_Idle = 0,
e_DLC_ContentState_Retrieving,
e_DLC_ContentState_Retrieved
};
enum eTMSContentState {
e_TMS_ContentState_Idle = 0,
e_TMS_ContentState_Queued,
e_TMS_ContentState_Retrieving,
e_TMS_ContentState_Retrieved
};
enum eXUID {
eXUID_Undefined = 0,
eXUID_NoName, // name not needed
eXUID_Notch,
eXUID_Carl,
eXUID_Daniel,
eXUID_Deadmau5,
eXUID_DannyBStyle,
eXUID_JulianClark,
eXUID_Millionth,
eXUID_4JPaddy,
eXUID_4JStuart,
eXUID_4JDavid,
eXUID_4JRichard,
eXUID_4JSteven,
};
enum _eTerrainFeatureType {
eTerrainFeature_None = 0,
eTerrainFeature_Stronghold,
eTerrainFeature_Mineshaft,
eTerrainFeature_Village,
eTerrainFeature_Ravine,
eTerrainFeature_NetherFortress,
eTerrainFeature_StrongholdEndPortal,
eTerrainFeature_Count
};
// 4J Stu - Whend adding new options you should consider whether having them on
// should disable achievements, and if so add them to the
// CanRecordStatsAndAchievements function 4J Stu - These options are now saved
// in save data, so new options can ONLY be added to the end
enum eGameHostOption {
eGameHostOption_Difficulty = 0,
eGameHostOption_OnlineGame, // Unused
eGameHostOption_InviteOnly, // Unused
eGameHostOption_FriendsOfFriends,
eGameHostOption_Gamertags,
eGameHostOption_Tutorial, // special case
eGameHostOption_GameType,
eGameHostOption_LevelType, // flat or default
eGameHostOption_Structures,
eGameHostOption_BonusChest,
eGameHostOption_HasBeenInCreative,
eGameHostOption_PvP,
eGameHostOption_TrustPlayers,
eGameHostOption_TNT,
eGameHostOption_FireSpreads,
eGameHostOption_CheatsEnabled, // special case
eGameHostOption_HostCanFly,
eGameHostOption_HostCanChangeHunger,
eGameHostOption_HostCanBeInvisible,
eGameHostOption_BedrockFog,
eGameHostOption_NoHUD,
eGameHostOption_WorldSize,
eGameHostOption_All,
eGameHostOption_DisableSaving,
eGameHostOption_WasntSaveOwner, // Added for PS3 save transfer, so we can
// add a nice message in the future instead
// of the creative mode one
eGameHostOption_MobGriefing,
eGameHostOption_KeepInventory,
eGameHostOption_DoMobSpawning,
eGameHostOption_DoMobLoot,
eGameHostOption_DoTileDrops,
eGameHostOption_NaturalRegeneration,
eGameHostOption_DoDaylightCycle,
};
// 4J-PB - If any new DLC items are added to the TMSFiles, this array needs
// updated
enum EHTMLFontSize {
eHTMLSize_Normal,
eHTMLSize_Splitscreen,
eHTMLSize_Tutorial,
eHTMLSize_EndPoem,
eHTMLSize_COUNT,
};
enum eMCLang {
eMCLang_null = 0,
eMCLang_enUS,
eMCLang_enGB,
eMCLang_enIE,
eMCLang_enAU,
eMCLang_enNZ,
eMCLang_enCA,
eMCLang_jaJP,
eMCLang_deDE,
eMCLang_deAT,
eMCLang_frFR,
eMCLang_frCA,
eMCLang_esES,
eMCLang_esMX,
eMCLang_itIT,
eMCLang_koKR,
eMCLang_ptPT,
eMCLang_ptBR,
eMCLang_ruRU,
eMCLang_nlNL,
eMCLang_fiFI,
eMCLang_svSV,
eMCLang_daDA,
eMCLang_noNO,
eMCLang_plPL,
eMCLang_trTR,
eMCLang_elEL,
eMCLang_csCS,
eMCLang_zhCHT,
eMCLang_laLAS,
eMCLang_zhSG,
eMCLang_zhCN,
eMCLang_zhHK,
eMCLang_zhTW,
eMCLang_nlBE,
eMCLang_daDK,
eMCLang_frBE,
eMCLang_frCH,
eMCLang_deCH,
eMCLang_nbNO,
eMCLang_enGR,
eMCLang_enHK,
eMCLang_enSA,
eMCLang_enHU,
eMCLang_enIN,
eMCLang_enIL,
eMCLang_enSG,
eMCLang_enSK,
eMCLang_enZA,
eMCLang_enCZ,
eMCLang_enAE,
eMCLang_esAR,
eMCLang_esCL,
eMCLang_esCO,
eMCLang_esUS,
eMCLang_svSE,
eMCLang_csCZ,
eMCLang_elGR,
eMCLang_nnNO,
eMCLang_skSK,
eMCLang_hans,
eMCLang_hant,
};
+194
View File
@@ -0,0 +1,194 @@
#pragma once
#include <cstdint>
#include "platform/sdl2/Storage.h"
#include "app/common/App_Defines.h"
#include "app/common/App_enums.h"
#include "app/common/src/Tutorial/TutorialEnum.h"
#include "app/common/src/UI/All Platforms/UIEnums.h"
#include "app/include/NetTypes.h"
#include "app/include/SkinBox.h"
#include "app/include/XboxStubs.h"
typedef struct {
wchar_t* wchFilename;
eFileExtensionType eEXT;
eTMSFileType eTMSType;
std::uint8_t* pbData;
unsigned int uiSize;
int iConfig; // used for texture pack data files
} TMS_FILE;
typedef struct {
std::uint8_t* pbData;
unsigned int byteCount;
std::uint8_t ucRefCount;
} MEMDATA, *PMEMDATA;
typedef struct {
unsigned int dwNotification;
unsigned int uiParam;
} NOTIFICATION, *PNOTIFICATION;
typedef struct {
bool bSettingsChanged;
unsigned char ucMusicVolume;
unsigned char ucSoundFXVolume;
unsigned char ucSensitivity;
unsigned char ucGamma;
unsigned char ucPad01; // 1 byte of padding inserted here
unsigned short usBitmaskValues; // bit 0,1 - difficulty
// bit 2 - view bob
// bit 3 - player visible in a map
// bit 4,5 - control scheme
// bit 6 - invert look
// bit 7 - southpaw
// bit 8 - splitscreen vertical
// 4J-PB - Adding new values for interim TU for 1.6.6
// bit 9 - Display gamertags in splitscreen
// bit 10 - Disable/Enable hints
// bit 11,12,13,14 - Autosave frequency - 0 = Off, 8 = (8*15 minutes)
// = 2 hours bit 15 Tooltips
// debug values
unsigned int uiDebugBitmask;
// block off space to use for whatever we want (e.g bitflags for storing
// things the player has done in the game, so we can flag the first time
// they do things, such as sleep)
union {
struct {
unsigned char ucTutorialCompletion[TUTORIAL_PROFILE_STORAGE_BYTES];
// adding new flags for interim TU to 1.6.6
// A value that encodes the skin that the player has set as their
// default
std::uint32_t dwSelectedSkin;
// In-Menu sensitivity
unsigned char ucMenuSensitivity;
unsigned char ucInterfaceOpacity;
unsigned char ucPad02; // 2 bytes of padding added here
unsigned char usPad03;
// Adding another bitmask flag for more settings for 1.8.2
unsigned int
uiBitmaskValues; // 0x00000001 - eGameSetting_Clouds - on
// 0x00000002 - eGameSetting_GameSetting_Online - on
// 0x00000004 - eGameSetting_GameSetting_Invite - off
// 0x00000008 - eGameSetting_GameSetting_FriendsOfFriends - on
// 0x00000010 - eGameSetting_PSVita_NetworkModeAdhoc - on
// TU 5
// 0x00000030 - eGameSetting_DisplayUpdateMessage - 3 - counts down
// to zero TU 6 0x00000040 - eGameSetting_BedrockFog - off
// 0x00000080 - eGameSetting_DisplayHUD - on
// 0x00000100 - eGameSetting_DisplayHand - on
// TU 7
// 0x00000200 - eGameSetting_CustomSkinAnim - on
// TU9
// // 0x00000400 - eGameSetting_DeathMessages - on
// Adding another bitmask to store "special" completion tasks for
// the tutorial
unsigned int uiSpecialTutorialBitmask;
// A value that encodes the cape that the player has set
std::uint32_t dwSelectedCape;
unsigned int uiFavoriteSkinA[MAX_FAVORITE_SKINS];
unsigned char ucCurrentFavoriteSkinPos;
// TU13
unsigned int
uiMashUpPackWorldsDisplay; // bitmask to enable/disable the
// display of the individual mash-up
// pack worlds
// PS3 1.05 - Adding Greek, so need a language
unsigned char ucLanguage;
// 29/Oct/2014 - Language selector.
unsigned char ucLocale;
// 4J Stu - See comment for GAME_SETTINGS_PROFILE_DATA_BYTES below
// was 192
// unsigned char
// ucUnused[192-TUTORIAL_PROFILE_STORAGE_BYTES-sizeof(uint32_t)-sizeof(char)-sizeof(char)-sizeof(char)-sizeof(char)-sizeof(int32_t)-sizeof(int32_t)-sizeof(uint32_t)];
// 4J-PB - don't need to define the padded space, the union with
// ucReservedSpace will make the sizeof GAME_SETTINGS correct
};
unsigned char ucReservedSpace[192];
};
} GAME_SETTINGS;
typedef struct {
PlayerUID xuid;
char pszLevelName[14];
} BANNEDLISTDATA, *PBANNEDLISTDATA;
typedef std::vector<PBANNEDLISTDATA> VBANNEDLIST;
typedef struct {
int iPad;
eXuiAction action;
} XuiActionParam;
// tips
typedef struct {
int iSortValue;
int uiStringID;
} TIPSTRUCT;
typedef struct {
eXUID eXuid;
wchar_t wchCape[MAX_CAPENAME_SIZE];
wchar_t wchSkin[MAX_CAPENAME_SIZE];
} MOJANG_DATA;
typedef struct {
eDLCContentType eDLCType;
uint64_t ullOfferID_Full;
uint64_t ullOfferID_Trial;
wchar_t wchBanner[MAX_BANNERNAME_SIZE];
wchar_t wchDataFile[MAX_BANNERNAME_SIZE];
int iGender;
int iConfig;
unsigned int uiSortIndex;
} DLC_INFO;
typedef struct {
int x, z;
_eTerrainFeatureType eTerrainFeature;
} FEATURE_DATA;
// banned list
typedef struct {
std::uint8_t* pBannedList;
unsigned int byteCount;
} BANNEDLIST;
typedef struct _DLCRequest {
std::uint32_t dwType;
eDLCContentState eState;
} DLCRequest;
typedef struct _TMSPPRequest {
eTMSContentState eState;
eDLCContentType eType;
C4JStorage::eGlobalStorage eStorageFacility;
C4JStorage::eTMS_FILETYPEVAL eFileTypeVal;
// char szFilename[MAX_TMSFILENAME_SIZE];
int (*CallbackFunc)(void*, int, int, C4JStorage::PTMSPP_FILEDATA,
const char* szFilename);
wchar_t wchFilename[MAX_TMSFILENAME_SIZE];
void* lpCallbackParam;
} TMSPPRequest;
typedef std::pair<EUIScene, HXUIOBJ> SceneStackPair;
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
#pragma once
// 3 bit user index
// 5 bits alpha
// 1 bit decoration
// 3 bits poptime
// 8 bits unused // was 11 bits aux val but needed 15 bits for potions so moved
// to item bitmask 6 bits count 6 bits scale
// uiCount is up to 64, but can't ever be 0, so to make it 6 bits, subtract one
// from the packing, and add one on the unpacking
#define MAKE_SLOTDISPLAY_DATA_BITMASK(uiUserIndex, uiAlpha, bDecorations, \
uiCount, uiScale, uiPopTime) \
((((uiUserIndex & 0x7) << 29) | (uiAlpha & 0x1F) << 24) | \
(bDecorations ? 0x800000 : 0) | ((uiPopTime & 0x7) << 20) | \
((uiCount - 1) << 6) | (uiScale & 0x3F))
#define GET_SLOTDISPLAY_USERINDEX_FROM_DATA_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) >> 29) & 0x7)
#define GET_SLOTDISPLAY_ALPHA_FROM_DATA_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) >> 24) & 0x1F)
#define GET_SLOTDISPLAY_DECORATIONS_FROM_DATA_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) & 0x800000) ? true : false)
// #define GET_SLOTDISPLAY_AUXVAL_FROM_DATA_BITMASK(uiBitmask)
// ((((unsigned long)uiBitmask)>>12)&0x7FF)
#define GET_SLOTDISPLAY_COUNT_FROM_DATA_BITMASK(uiBitmask) \
(((((unsigned int)uiBitmask) >> 6) & 0x3F) + 1)
#define GET_SLOTDISPLAY_SCALE_FROM_DATA_BITMASK(uiBitmask) \
(((unsigned int)uiBitmask) & 0x3F)
#define GET_SLOTDISPLAY_POPTIME_FROM_DATA_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) >> 20) & 0x7)
// 16 bits for id (either item id or xzp icon id)
// 15 bits for aux value
// 1 bit for foil
#define MAKE_SLOTDISPLAY_ITEM_BITMASK(uiId, uiAuxValue, bFoil) \
((uiId & 0xFFFF) | ((uiAuxValue & 0x7FFF) << 16) | (bFoil ? 0x80000000 : 0))
#define GET_SLOTDISPLAY_ID_FROM_ITEM_BITMASK(uiBitmask) \
(((unsigned int)uiBitmask) & 0xFFFF)
#define GET_SLOTDISPLAY_AUXVAL_FROM_ITEM_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) >> 16) & 0x7FFF)
#define GET_SLOTDISPLAY_FOIL_FROM_ITEM_BITMASK(uiBitmask) \
((((unsigned int)uiBitmask) & 0x80000000) ? true : false)
// For encoding the players skin selection in their profile
// bDlcSkin = false is a players skin, bDlcSkin = true is a DLC skin
#define MAKE_SKIN_BITMASK(bDlcSkin, dwSkinId) \
((bDlcSkin ? 0x80000000 : 0) | (dwSkinId & 0x7FFFFFFF))
#define IS_SKIN_ID_IN_RANGE(dwSkinId) (dwSkinId <= 0x7FFFFFFF)
#define GET_DLC_SKIN_ID_FROM_BITMASK(uiBitmask) \
(((uint32_t)uiBitmask) & 0x7FFFFFFF)
#define GET_UGC_SKIN_ID_FROM_BITMASK(uiBitmask) \
(((uint32_t)uiBitmask) & 0x7FFFFFE0)
#define GET_DEFAULT_SKIN_ID_FROM_BITMASK(uiBitmask) \
(((uint32_t)uiBitmask) & 0x0000001F)
#define GET_IS_DLC_SKIN_FROM_BITMASK(uiBitmask) \
((((uint32_t)uiBitmask) & 0x80000000) ? true : false)
+53
View File
@@ -0,0 +1,53 @@
#pragma once
#include <array>
#include <atomic>
#include <condition_variable>
#include <cstddef>
#include <mutex>
#include "console_helpers/C4JThread.h"
class ShutdownManager {
public:
enum EThreadId {
eMainThread,
eLeaderboardThread,
eCommerceThread,
ePostProcessThread,
eRunUpdateThread,
eRenderChunkUpdateThread,
eServerThread,
eStorageManagerThreads,
eConnectionReadThreads,
eConnectionWriteThreads,
eEventQueueThreads,
eThreadIdCount
};
static void Initialise();
static void StartShutdown();
static void MainThreadHandleShutdown();
static void HasStarted(EThreadId threadId);
static void HasStarted(EThreadId threadId,
C4JThread::EventArray* eventArray);
static bool ShouldRun(EThreadId threadId);
static void HasFinished(EThreadId threadId);
private:
struct GroupState {
std::size_t started = 0;
std::size_t running = 0;
};
struct State {
std::mutex mutex;
std::condition_variable condition;
std::array<GroupState, eThreadIdCount> groups{};
std::atomic<bool> shutdownRequested{false};
};
static State& GetState();
};
@@ -0,0 +1,24 @@
#include "Consoles_SoundEngine.h"
bool ConsoleSoundEngine::GetIsPlayingStreamingCDMusic() {
return m_bIsPlayingStreamingCDMusic;
}
bool ConsoleSoundEngine::GetIsPlayingStreamingGameMusic() {
return m_bIsPlayingStreamingGameMusic;
}
void ConsoleSoundEngine::SetIsPlayingStreamingCDMusic(bool bVal) {
m_bIsPlayingStreamingCDMusic = bVal;
}
void ConsoleSoundEngine::SetIsPlayingStreamingGameMusic(bool bVal) {
m_bIsPlayingStreamingGameMusic = bVal;
}
bool ConsoleSoundEngine::GetIsPlayingEndMusic() { return m_bIsPlayingEndMusic; }
bool ConsoleSoundEngine::GetIsPlayingNetherMusic() {
return m_bIsPlayingNetherMusic;
}
void ConsoleSoundEngine::SetIsPlayingEndMusic(bool bVal) {
m_bIsPlayingEndMusic = bVal;
}
void ConsoleSoundEngine::SetIsPlayingNetherMusic(bool bVal) {
m_bIsPlayingNetherMusic = bVal;
}
@@ -0,0 +1,89 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "minecraft/sounds/SoundTypes.h"
class File;
typedef struct {
float x, y, z;
} AUDIO_VECTOR;
typedef struct {
bool bValid;
AUDIO_VECTOR vPosition;
AUDIO_VECTOR vOrientFront;
} AUDIO_LISTENER;
class Options;
class Mob;
class ConsoleSoundEngine {
public:
ConsoleSoundEngine()
: m_bIsPlayingStreamingCDMusic(false),
m_bIsPlayingStreamingGameMusic(false),
m_bIsPlayingEndMusic(false),
m_bIsPlayingNetherMusic(false) {}
virtual void tick(std::shared_ptr<Mob>* players, float a) = 0;
virtual void destroy() = 0;
virtual void play(int iSound, float x, float y, float z, float volume,
float pitch) = 0;
virtual void playStreaming(const std::wstring& name, float x, float y,
float z, float volume, float pitch,
bool bMusicDelay = true) = 0;
virtual void playUI(int iSound, float volume, float pitch) = 0;
virtual void updateMusicVolume(float fVal) = 0;
virtual void updateSystemMusicPlaying(bool isPlaying) = 0;
virtual void updateSoundEffectVolume(float fVal) = 0;
virtual void init(Options*) = 0;
virtual void add(const std::wstring& name, File* file) = 0;
virtual void addMusic(const std::wstring& name, File* file) = 0;
virtual void addStreaming(const std::wstring& name, File* file) = 0;
virtual char* ConvertSoundPathToName(const std::wstring& name,
bool bConvertSpaces) = 0;
virtual void playMusicTick() = 0;
virtual bool GetIsPlayingStreamingCDMusic();
virtual bool GetIsPlayingStreamingGameMusic();
virtual void SetIsPlayingStreamingCDMusic(bool bVal);
virtual void SetIsPlayingStreamingGameMusic(bool bVal);
virtual bool GetIsPlayingEndMusic();
virtual bool GetIsPlayingNetherMusic();
virtual void SetIsPlayingEndMusic(bool bVal);
virtual void SetIsPlayingNetherMusic(bool bVal);
static const wchar_t* wchSoundNames[eSoundType_MAX];
static const wchar_t* wchUISoundNames[eSFX_MAX];
public:
void tick();
void schedule(int iSound, float x, float y, float z, float volume,
float pitch, int delayTicks);
private:
class ScheduledSound {
public:
int iSound;
float x, y, z;
float volume, pitch;
int delay;
public:
ScheduledSound(int iSound, float x, float y, float z, float volume,
float pitch, int delay);
};
std::vector<ScheduledSound*> scheduledSounds;
virtual int initAudioHardware(int iMinSpeakers) = 0;
bool m_bIsPlayingStreamingCDMusic;
bool m_bIsPlayingStreamingGameMusic;
bool m_bIsPlayingEndMusic;
bool m_bIsPlayingNetherMusic;
};
File diff suppressed because it is too large Load Diff
+181
View File
@@ -0,0 +1,181 @@
#pragma once
class Mob;
class Options;
class C4JThread;
class Random;
#include <string>
#include "app/common/App_Defines.h"
#include "app/common/src/Audio/Consoles_SoundEngine.h"
#include "app/linux/Iggy/include/rrCore.h"
#include "minecraft/sounds/SoundTypes.h"
#include "miniaudio.h"
constexpr float SFX_3D_MIN_DISTANCE = 1.0f;
constexpr float SFX_3D_MAX_DISTANCE = 16.0f;
constexpr float SFX_3D_ROLLOFF = 0.5f;
constexpr float SFX_VOLUME_MULTIPLIER = 1.5f;
constexpr float SFX_MAX_GAIN = 1.5f;
enum eMUSICFILES {
eStream_Overworld_Calm1 = 0,
eStream_Overworld_Calm2,
eStream_Overworld_Calm3,
eStream_Overworld_hal1,
eStream_Overworld_hal2,
eStream_Overworld_hal3,
eStream_Overworld_hal4,
eStream_Overworld_nuance1,
eStream_Overworld_nuance2,
// Add the new music tracks
eStream_Overworld_Creative1,
eStream_Overworld_Creative2,
eStream_Overworld_Creative3,
eStream_Overworld_Creative4,
eStream_Overworld_Creative5,
eStream_Overworld_Creative6,
eStream_Overworld_Menu1,
eStream_Overworld_Menu2,
eStream_Overworld_Menu3,
eStream_Overworld_Menu4,
eStream_Overworld_piano1,
eStream_Overworld_piano2,
eStream_Overworld_piano3, // <-- make piano3 the last overworld one
// Nether
eStream_Nether1,
eStream_Nether2,
eStream_Nether3,
eStream_Nether4,
// The End
eStream_end_dragon,
eStream_end_end,
eStream_CD_1,
eStream_CD_2,
eStream_CD_3,
eStream_CD_4,
eStream_CD_5,
eStream_CD_6,
eStream_CD_7,
eStream_CD_8,
eStream_CD_9,
eStream_CD_10,
eStream_CD_11,
eStream_CD_12,
eStream_Max,
};
enum eMUSICTYPE {
eMusicType_None,
eMusicType_Game,
eMusicType_CD,
};
enum MUSIC_STREAMSTATE {
eMusicStreamState_Idle = 0,
eMusicStreamState_Stop,
eMusicStreamState_Stopping,
eMusicStreamState_Opening,
eMusicStreamState_OpeningCancel,
eMusicStreamState_Play,
eMusicStreamState_Playing,
eMusicStreamState_Completed
};
typedef struct {
F32 x, y, z, volume, pitch;
int iSound;
bool bIs3D;
bool bUseSoundsPitchVal;
#if defined(_DEBUG)
char chName[64];
#endif
} AUDIO_INFO;
struct MiniAudioSound {
ma_sound sound;
AUDIO_INFO info;
bool active;
};
class SoundEngine : public ConsoleSoundEngine {
static const int MAX_SAME_SOUNDS_PLAYING = 8; // 4J added
public:
SoundEngine();
virtual void destroy();
#if defined(_DEBUG)
void GetSoundName(char* szSoundName, int iSound);
#endif
virtual void play(int iSound, float x, float y, float z, float volume,
float pitch);
virtual void playStreaming(const std::wstring& name, float x, float y,
float z, float volume, float pitch,
bool bMusicDelay = true);
virtual void playUI(int iSound, float volume, float pitch);
virtual void playMusicTick();
virtual void updateMusicVolume(float fVal);
virtual void updateSystemMusicPlaying(bool isPlaying);
virtual void updateSoundEffectVolume(float fVal);
virtual void init(Options*);
virtual void tick(std::shared_ptr<Mob>* players,
float a); // 4J - updated to take array of local players
// rather than single one
virtual void add(const std::wstring& name, File* file);
virtual void addMusic(const std::wstring& name, File* file);
virtual void addStreaming(const std::wstring& name, File* file);
virtual char* ConvertSoundPathToName(const std::wstring& name,
bool bConvertSpaces = false);
bool isStreamingWavebankReady(); // 4J Added
int getMusicID(int iDomain);
int getMusicID(const std::wstring& name);
void SetStreamingSounds(int iOverworldMin, int iOverWorldMax,
int iNetherMin, int iNetherMax, int iEndMin,
int iEndMax, int iCD1);
void updateMiles(); // AP added so Vita can update all the Miles functions
// during the mixer callback
void playMusicUpdate();
private:
float getMasterMusicVolume();
// platform specific functions
int initAudioHardware(int iMinSpeakers) { return iMinSpeakers; }
#if defined(__linux__)
void updateMiniAudio();
#endif
int GetRandomishTrack(int iStart, int iEnd);
ma_engine m_engine;
ma_engine_config m_engineConfig;
ma_sound m_musicStream;
bool m_musicStreamActive;
static char m_szSoundPath[];
static char m_szMusicPath[];
static char m_szRedistName[];
static const char* m_szStreamFileA[eStream_Max];
AUDIO_LISTENER m_ListenerA[MAX_LOCAL_PLAYERS];
int m_validListenerCount;
Random* random;
int m_musicID;
int m_iMusicDelay;
int m_StreamState;
int m_MusicType;
AUDIO_INFO m_StreamingAudioInfo;
std::wstring m_CDMusic;
bool m_bSystemMusicPlaying;
float m_MasterMusicVolume;
float m_MasterEffectsVolume;
C4JThread* m_openStreamThread;
static int OpenStreamThreadProc(void* lpParameter);
char m_szStreamName[1024];
int CurrentSoundsPlaying[static_cast<int>(eSoundType_MAX) +
static_cast<int>(eSFX_MAX)];
// streaming music files - will be different for mash-up packs
int m_iStream_Overworld_Min, m_iStream_Overworld_Max;
int m_iStream_Nether_Min, m_iStream_Nether_Max;
int m_iStream_End_Min, m_iStream_End_Max;
int m_iStream_CD_1;
bool* m_bHeardTrackA;
};
+228
View File
@@ -0,0 +1,228 @@
#include "Consoles_SoundEngine.h"
#include "minecraft/sounds/SoundTypes.h"
const wchar_t* ConsoleSoundEngine::wchSoundNames[eSoundType_MAX] = {
L"mob/chicken/chicken", // eSoundType_MOB_CHICKEN_AMBIENT
L"mob/chicken/chickenhurt", // eSoundType_MOB_CHICKEN_HURT
L"mob/chicken/chickenplop", // eSoundType_MOB_CHICKENPLOP
L"mob/cow/say", // eSoundType_MOB_COW_AMBIENT
L"mob/cow/hurt", // eSoundType_MOB_COW_HURT
L"mob/pig/pig", // eSoundType_MOB_PIG_AMBIENT
L"mob/pig/pigdeath", // eSoundType_MOB_PIG_DEATH
L"mob/sheep/sheep", // eSoundType_MOB_SHEEP_AMBIENT
L"mob/wolf/growl", // eSoundType_MOB_WOLF_GROWL
L"mob/wolf/whine", // eSoundType_MOB_WOLF_WHINE
L"mob/wolf/panting", // eSoundType_MOB_WOLF_PANTING
L"mob/wolf/bark", // eSoundType_MOB_WOLF_BARK
L"mob/wolf/hurt", // eSoundType_MOB_WOLF_HURT
L"mob/wolf/death", // eSoundType_MOB_WOLF_DEATH
L"mob/wolf/shake", // eSoundType_MOB_WOLF_SHAKE
L"mob/blaze/breathe", // eSoundType_MOB_BLAZE_BREATHE
L"mob/blaze/hit", // eSoundType_MOB_BLAZE_HURT
L"mob/blaze/death", // eSoundType_MOB_BLAZE_DEATH
L"mob/ghast/moan", // eSoundType_MOB_GHAST_MOAN
L"mob/ghast/scream", // eSoundType_MOB_GHAST_SCREAM
L"mob/ghast/death", // eSoundType_MOB_GHAST_DEATH
L"mob/ghast/fireball", // eSoundType_MOB_GHAST_FIREBALL
L"mob/ghast/charge", // eSoundType_MOB_GHAST_CHARGE
L"mob/endermen/idle", // eSoundType_MOB_ENDERMEN_IDLE
L"mob/endermen/hit", // eSoundType_MOB_ENDERMEN_HIT
L"mob/endermen/death", // eSoundType_MOB_ENDERMEN_DEATH
L"mob/endermen/portal", // eSoundType_MOB_ENDERMEN_PORTAL
L"mob/zombiepig/zpig", // eSoundType_MOB_ZOMBIEPIG_AMBIENT
L"mob/zombiepig/zpighurt", // eSoundType_MOB_ZOMBIEPIG_HURT
L"mob/zombiepig/zpigdeath", // eSoundType_MOB_ZOMBIEPIG_DEATH
L"mob/zombiepig/zpigangry", // eSoundType_MOB_ZOMBIEPIG_ZPIGANGRY
L"mob/silverfish/say", // eSoundType_MOB_SILVERFISH_AMBIENT,
L"mob/silverfish/hit", // eSoundType_MOB_SILVERFISH_HURT
L"mob/silverfish/kill", // eSoundType_MOB_SILVERFISH_DEATH,
L"mob/silverfish/step", // eSoundType_MOB_SILVERFISH_STEP,
L"mob/skeleton/skeleton", // eSoundType_MOB_SKELETON_AMBIENT,
L"mob/skeleton/skeletonhurt", // eSoundType_MOB_SKELETON_HURT,
L"mob/spider/spider", // eSoundType_MOB_SPIDER_AMBIENT,
L"mob/spider/spiderdeath", // eSoundType_MOB_SPIDER_DEATH,
L"mob/slime/slime", // eSoundType_MOB_SLIME,
L"mob/slime/slimeattack", // eSoundType_MOB_SLIME_ATTACK,
L"mob/creeper/creeper", // eSoundType_MOB_CREEPER_HURT,
L"mob/creeper/creeperdeath", // eSoundType_MOB_CREEPER_DEATH,
L"mob/zombie/zombie", // eSoundType_MOB_ZOMBIE_AMBIENT,
L"mob/zombie/zombiehurt", // eSoundType_MOB_ZOMBIE_HURT,
L"mob/zombie/zombiedeath", // eSoundType_MOB_ZOMBIE_DEATH,
L"mob/zombie/wood", // eSoundType_MOB_ZOMBIE_WOOD,
L"mob/zombie/woodbreak", // eSoundType_MOB_ZOMBIE_WOOD_BREAK,
L"mob/zombie/metal", // eSoundType_MOB_ZOMBIE_METAL,
L"mob/magmacube/big", // eSoundType_MOB_MAGMACUBE_BIG,
L"mob/magmacube/small", // eSoundType_MOB_MAGMACUBE_SMALL,
L"mob/cat/purr", // eSoundType_MOB_CAT_PURR
L"mob/cat/purreow", // eSoundType_MOB_CAT_PURREOW
L"mob/cat/meow", // eSoundType_MOB_CAT_MEOW
// 4J-PB - correct the name of the event for hitting ocelots
L"mob/cat/hitt", // eSoundType_MOB_CAT_HITT
// L"mob.irongolem.throw", //
// eSoundType_MOB_IRONGOLEM_THROW L"mob.irongolem.hit",
//// eSoundType_MOB_IRONGOLEM_HIT L"mob.irongolem.death",
//// eSoundType_MOB_IRONGOLEM_DEATH L"mob.irongolem.walk",
//// eSoundType_MOB_IRONGOLEM_WALK
L"random/bow", // eSoundType_RANDOM_BOW,
L"random/bowhit", // eSoundType_RANDOM_BOW_HIT,
L"random/explode", // eSoundType_RANDOM_EXPLODE,
L"random/fizz", // eSoundType_RANDOM_FIZZ,
L"random/pop", // eSoundType_RANDOM_POP,
L"random/fuse", // eSoundType_RANDOM_FUSE,
L"random/drink", // eSoundType_RANDOM_DRINK,
L"random/eat", // eSoundType_RANDOM_EAT,
L"random/burp", // eSoundType_RANDOM_BURP,
L"random/splash", // eSoundType_RANDOM_SPLASH,
L"random/click", // eSoundType_RANDOM_CLICK,
L"random/glass", // eSoundType_RANDOM_GLASS,
L"random/orb", // eSoundType_RANDOM_ORB,
L"random/break", // eSoundType_RANDOM_BREAK,
L"random/chestopen", // eSoundType_RANDOM_CHEST_OPEN,
L"random/chestclosed", // eSoundType_RANDOM_CHEST_CLOSE,
L"random/door_open", // eSoundType_RANDOM_DOOR_OPEN,
L"random/door_close", // eSoundType_RANDOM_DOOR_CLOSE,
L"ambient/weather/rain", // eSoundType_AMBIENT_WEATHER_RAIN,
L"ambient/weather/thunder", // eSoundType_AMBIENT_WEATHER_THUNDER,
L"ambient/cave/cave", // eSoundType_CAVE_CAVE, DON'T USE FOR XBOX 360!!!
L"portal/portal", // eSoundType_PORTAL_PORTAL,
// 4J-PB - added a couple that were still using std::wstring
L"portal/trigger", // eSoundType_PORTAL_TRIGGER
L"portal/travel", // eSoundType_PORTAL_TRAVEL
L"fire/ignite", // eSoundType_FIRE_IGNITE,
L"fire/fire", // eSoundType_FIRE_FIRE,
L"damage/hit", // eSoundType_DAMAGE_HURT,
L"damage/fallsmall", // eSoundType_DAMAGE_FALL_SMALL,
L"damage/fallbig", // eSoundType_DAMAGE_FALL_BIG,
L"note/harp", // eSoundType_NOTE_HARP,
L"note/bd", // eSoundType_NOTE_BD,
L"note/snare", // eSoundType_NOTE_SNARE,
L"note/hat", // eSoundType_NOTE_HAT,
L"note/bassattack", // eSoundType_NOTE_BASSATTACK,
L"tile/piston.in", // eSoundType_TILE_PISTON_IN,
L"tile/piston.out", // eSoundType_TILE_PISTON_OUT,
L"liquid/water", // eSoundType_LIQUID_WATER,
L"liquid/lavapop", // eSoundType_LIQUID_LAVA_POP,
L"liquid/lava", // eSoundType_LIQUID_LAVA,
L"step/stone", // eSoundType_STEP_STONE,
L"step/wood", // eSoundType_STEP_WOOD,
L"step/gravel", // eSoundType_STEP_GRAVEL,
L"step/grass", // eSoundType_STEP_GRASS,
L"step/metal", // eSoundType_STEP_METAL,
L"step/cloth", // eSoundType_STEP_CLOTH,
L"step/sand", // eSoundType_STEP_SAND,
// below this are the additional sounds from the second soundbank
L"mob/enderdragon/end", // eSoundType_MOB_ENDERDRAGON_END
L"mob/enderdragon/growl", // eSoundType_MOB_ENDERDRAGON_GROWL
L"mob/enderdragon/hit", // eSoundType_MOB_ENDERDRAGON_HIT
L"mob/enderdragon/wings", // eSoundType_MOB_ENDERDRAGON_MOVE
L"mob/irongolem/throw", // eSoundType_MOB_IRONGOLEM_THROW
L"mob/irongolem/hit", // eSoundType_MOB_IRONGOLEM_HIT
L"mob/irongolem/death", // eSoundType_MOB_IRONGOLEM_DEATH
L"mob/irongolem/walk", // eSoundType_MOB_IRONGOLEM_WALK
// TU14
L"damage/thorns", // eSoundType_DAMAGE_THORNS
L"random/anvil_break", // eSoundType_RANDOM_ANVIL_BREAK
L"random/anvil_land", // eSoundType_RANDOM_ANVIL_LAND
L"random/anvil_use", // eSoundType_RANDOM_ANVIL_USE
L"mob/villager/haggle", // eSoundType_MOB_VILLAGER_HAGGLE
L"mob/villager/idle", // eSoundType_MOB_VILLAGER_IDLE
L"mob/villager/hit", // eSoundType_MOB_VILLAGER_HIT
L"mob/villager/death", // eSoundType_MOB_VILLAGER_DEATH
L"mob/villager/yes", // eSoundType_MOB_VILLAGER_YES
L"mob/villager/no", // eSoundType_MOB_VILLAGER_NO
L"mob/zombie/infect", // eSoundType_MOB_ZOMBIE_INFECT
L"mob/zombie/unfect", // eSoundType_MOB_ZOMBIE_UNFECT
L"mob/zombie/remedy", // eSoundType_MOB_ZOMBIE_REMEDY
L"step/snow", // eSoundType_STEP_SNOW
L"step/ladder", // eSoundType_STEP_LADDER
L"dig/cloth", // eSoundType_DIG_CLOTH
L"dig/grass", // eSoundType_DIG_GRASS
L"dig/gravel", // eSoundType_DIG_GRAVEL
L"dig/sand", // eSoundType_DIG_SAND
L"dig/snow", // eSoundType_DIG_SNOW
L"dig/stone", // eSoundType_DIG_STONE
L"dig/wood", // eSoundType_DIG_WOOD
// 1.6.4
L"fireworks/launch", // eSoundType_FIREWORKS_LAUNCH,
L"fireworks/blast", // eSoundType_FIREWORKS_BLAST,
L"fireworks/blast_far", // eSoundType_FIREWORKS_BLAST_FAR,
L"fireworks/large_blast", // eSoundType_FIREWORKS_LARGE_BLAST,
L"fireworks/large_blast_far", // eSoundType_FIREWORKS_LARGE_BLAST_FAR,
L"fireworks/twinkle", // eSoundType_FIREWORKS_TWINKLE,
L"fireworks/twinkle_far", // eSoundType_FIREWORKS_TWINKLE_FAR,
L"mob/bat/idle", // eSoundType_MOB_BAT_IDLE,
L"mob/bat/hurt", // eSoundType_MOB_BAT_HURT,
L"mob/bat/death", // eSoundType_MOB_BAT_DEATH,
L"mob/bat/takeoff", // eSoundType_MOB_BAT_TAKEOFF,
L"mob/wither/spawn", // eSoundType_MOB_WITHER_SPAWN,
L"mob/wither/idle", // eSoundType_MOB_WITHER_IDLE,
L"mob/wither/hurt", // eSoundType_MOB_WITHER_HURT,
L"mob/wither/death", // eSoundType_MOB_WITHER_DEATH,
L"mob/wither/shoot", // eSoundType_MOB_WITHER_SHOOT,
L"mob/cow/step", // eSoundType_MOB_COW_STEP,
L"mob/chicken/step", // eSoundType_MOB_CHICKEN_STEP,
L"mob/pig/step", // eSoundType_MOB_PIG_STEP,
L"mob/enderman/stare", // eSoundType_MOB_ENDERMAN_STARE,
L"mob/enderman/scream", // eSoundType_MOB_ENDERMAN_SCREAM,
L"mob/sheep/shear", // eSoundType_MOB_SHEEP_SHEAR,
L"mob/sheep/step", // eSoundType_MOB_SHEEP_STEP,
L"mob/skeleton.death", // eSoundType_MOB_SKELETON_DEATH,
L"mob/skeleton/step", // eSoundType_MOB_SKELETON_STEP,
L"mob/spider/step", // eSoundType_MOB_SPIDER_STEP,
L"mob/wolf/step", // eSoundType_MOB_WOLF_STEP,
L"mob/zombie/step", // eSoundType_MOB_ZOMBIE_STEP,
L"liquid/swim", // eSoundType_LIQUID_SWIM,
L"mob/horse/land", // eSoundType_MOB_HORSE_LAND,
L"mob/horse/armor", // eSoundType_MOB_HORSE_ARMOR,
L"mob/horse/leather", // eSoundType_MOB_HORSE_LEATHER,
L"mob/horse/zombie.death", // eSoundType_MOB_HORSE_ZOMBIE_DEATH,
L"mob/horse/skeleton.death", // eSoundType_MOB_HORSE_SKELETON_DEATH,
L"mob/horse/donkey.death", // eSoundType_MOB_HORSE_DONKEY_DEATH,
L"mob/horse/death", // eSoundType_MOB_HORSE_DEATH,
L"mob/horse/zombie.hit", // eSoundType_MOB_HORSE_ZOMBIE_HIT,
L"mob/horse/skeleton.hit", // eSoundType_MOB_HORSE_SKELETON_HIT,
L"mob/horse/donkey.hit", // eSoundType_MOB_HORSE_DONKEY_HIT,
L"mob/horse/hit", // eSoundType_MOB_HORSE_HIT,
L"mob/horse/zombie.idle", // eSoundType_MOB_HORSE_ZOMBIE_IDLE,
L"mob/horse/skeleton.idle", // eSoundType_MOB_HORSE_SKELETON_IDLE,
L"mob/horse/donkey.idle", // eSoundType_MOB_HORSE_DONKEY_IDLE,
L"mob/horse/idle", // eSoundType_MOB_HORSE_IDLE,
L"mob/horse/donkey.angry", // eSoundType_MOB_HORSE_DONKEY_ANGRY,
L"mob/horse/angry", // eSoundType_MOB_HORSE_ANGRY,
L"mob/horse/gallop", // eSoundType_MOB_HORSE_GALLOP,
L"mob/horse/breathe", // eSoundType_MOB_HORSE_BREATHE,
L"mob/horse/wood", // eSoundType_MOB_HORSE_WOOD,
L"mob/horse/soft", // eSoundType_MOB_HORSE_SOFT,
L"mob/horse/jump", // eSoundType_MOB_HORSE_JUMP,
L"mob/witch/idle", // eSoundType_MOB_WITCH_IDLE, <---
// missing
L"mob/witch/hurt", // eSoundType_MOB_WITCH_HURT, <---
// missing
L"mob/witch/death", // eSoundType_MOB_WITCH_DEATH, <---
// missing
L"mob/slime/big", // eSoundType_MOB_SLIME_BIG,
L"mob/slime/small", // eSoundType_MOB_SLIME_SMALL,
L"eating", // eSoundType_EATING <--- missing
L"random/levelup", // eSoundType_RANDOM_LEVELUP
// 4J-PB - Some sounds were updated, but we can't do that for the 360 or we
// have to do a new sound bank instead, we'll add the sounds as new ones and
// change the code to reference them
L"fire/new_ignite",
};
const wchar_t* ConsoleSoundEngine::wchUISoundNames[eSFX_MAX] = {
L"back", L"craft", L"craftfail", L"focus", L"press", L"scroll",
};
@@ -0,0 +1,65 @@
#pragma once
#define VER_PRODUCTMAJORVERSION 0
#define VER_PRODUCTMINORVERSION 0
// This goes up with each build
// 4J-JEV: This value is extracted with a regex so it can be placed as the
// version in the AppX manifest on Durango.
#define VER_PRODUCTBUILD 560
// This goes up if there is any change to network traffic or code in a build
#define VER_NETWORK 560
#define VER_PRODUCTBUILD_QFE 0
#define VER_FILEVERSION_STRING "1.6"
#define VER_PRODUCTVERSION_STRING VER_FILEVERSION_STRING
#define VER_FILEVERSION_STRING_W L"1.6"
#define VER_PRODUCTVERSION_STRING_W VER_FILEVERSION_STRING_W
#define VER_FILEBETA_STR ""
#undef VER_FILEVERSION
#define VER_FILEVERSION \
VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION, VER_PRODUCTBUILD, \
VER_PRODUCTBUILD_QFE
#define VER_PRODUCTVERSION \
VER_PRODUCTMAJORVERSION, VER_PRODUCTMINORVERSION, VER_PRODUCTBUILD, \
VER_PRODUCTBUILD_QFE
#if (VER_PRODUCTBUILD < 10)
#define VER_FILEBPAD "000"
#define VER_FILEBPAD_W L"000"
#elif (VER_PRODUCTBUILD < 100)
#define VER_FILEBPAD "00"
#define VER_FILEBPAD_W L"00"
#elif (VER_PRODUCTBUILD < 1000)
#define VER_FILEBPAD "0"
#define VER_FILEBPAD_W L"0"
#else
#define VER_FILEBPAD
#define VER_FILEBPAD_W
#endif
#define VER_WIDE_PREFIX(x) L##x
#define VER_FILEVERSION_STR2(x, y) \
VER_FILEVERSION_STRING "." VER_FILEBPAD #x "." #y
#define VER_FILEVERSION_STR2_W(x, y) \
VER_FILEVERSION_STRING_W L"." VER_FILEBPAD_W VER_WIDE_PREFIX( \
#x) L"." VER_WIDE_PREFIX(#y)
#define VER_FILEVERSION_STR1(x, y) VER_FILEVERSION_STR2(x, y)
#define VER_FILEVERSION_STR1_W(x, y) VER_FILEVERSION_STR2_W(x, y)
#undef VER_FILEVERSION_STR
#define VER_FILEVERSION_STR \
VER_FILEVERSION_STR1(VER_PRODUCTBUILD, VER_PRODUCTBUILD_QFE)
#define VER_PRODUCTVERSION_STR \
VER_FILEVERSION_STR1(VER_PRODUCTBUILD, VER_PRODUCTBUILD_QFE)
#define VER_FILEVERSION_STR_W \
VER_FILEVERSION_STR1_W(VER_PRODUCTBUILD, VER_PRODUCTBUILD_QFE)
#define VER_PRODUCTVERSION_STR_W \
VER_FILEVERSION_STR1_W(VER_PRODUCTBUILD, VER_PRODUCTBUILD_QFE)
#if (VER_PRODUCTBUILD_QFE >= 256)
#error "QFE number cannot exceed 255"
#endif
@@ -0,0 +1,385 @@
#include "ColourTable.h"
#include <cstring>
#include <utility>
#include <vector>
#include "app/common/App_enums.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/ByteArrayInputStream.h"
#include "java/InputOutputStream/DataInputStream.h"
std::unordered_map<std::wstring, eMinecraftColour>
ColourTable::s_colourNamesMap;
const wchar_t* ColourTable::ColourTableElements[eMinecraftColour_COUNT] = {
L"NOTSET",
L"Foliage_Evergreen",
L"Foliage_Birch",
L"Foliage_Default",
L"Foliage_Common",
L"Foliage_Ocean",
L"Foliage_Plains",
L"Foliage_Desert",
L"Foliage_ExtremeHills",
L"Foliage_Forest",
L"Foliage_Taiga",
L"Foliage_Swampland",
L"Foliage_River",
L"Foliage_Hell",
L"Foliage_Sky",
L"Foliage_FrozenOcean",
L"Foliage_FrozenRiver",
L"Foliage_IcePlains",
L"Foliage_IceMountains",
L"Foliage_MushroomIsland",
L"Foliage_MushroomIslandShore",
L"Foliage_Beach",
L"Foliage_DesertHills",
L"Foliage_ForestHills",
L"Foliage_TaigaHills",
L"Foliage_ExtremeHillsEdge",
L"Foliage_Jungle",
L"Foliage_JungleHills",
L"Grass_Common",
L"Grass_Ocean",
L"Grass_Plains",
L"Grass_Desert",
L"Grass_ExtremeHills",
L"Grass_Forest",
L"Grass_Taiga",
L"Grass_Swampland",
L"Grass_River",
L"Grass_Hell",
L"Grass_Sky",
L"Grass_FrozenOcean",
L"Grass_FrozenRiver",
L"Grass_IcePlains",
L"Grass_IceMountains",
L"Grass_MushroomIsland",
L"Grass_MushroomIslandShore",
L"Grass_Beach",
L"Grass_DesertHills",
L"Grass_ForestHills",
L"Grass_TaigaHills",
L"Grass_ExtremeHillsEdge",
L"Grass_Jungle",
L"Grass_JungleHills",
L"Water_Ocean",
L"Water_Plains",
L"Water_Desert",
L"Water_ExtremeHills",
L"Water_Forest",
L"Water_Taiga",
L"Water_Swampland",
L"Water_River",
L"Water_Hell",
L"Water_Sky",
L"Water_FrozenOcean",
L"Water_FrozenRiver",
L"Water_IcePlains",
L"Water_IceMountains",
L"Water_MushroomIsland",
L"Water_MushroomIslandShore",
L"Water_Beach",
L"Water_DesertHills",
L"Water_ForestHills",
L"Water_TaigaHills",
L"Water_ExtremeHillsEdge",
L"Water_Jungle",
L"Water_JungleHills",
L"Sky_Ocean",
L"Sky_Plains",
L"Sky_Desert",
L"Sky_ExtremeHills",
L"Sky_Forest",
L"Sky_Taiga",
L"Sky_Swampland",
L"Sky_River",
L"Sky_Hell",
L"Sky_Sky",
L"Sky_FrozenOcean",
L"Sky_FrozenRiver",
L"Sky_IcePlains",
L"Sky_IceMountains",
L"Sky_MushroomIsland",
L"Sky_MushroomIslandShore",
L"Sky_Beach",
L"Sky_DesertHills",
L"Sky_ForestHills",
L"Sky_TaigaHills",
L"Sky_ExtremeHillsEdge",
L"Sky_Jungle",
L"Sky_JungleHills",
L"Tile_RedstoneDust",
L"Tile_RedstoneDustUnlit",
L"Tile_RedstoneDustLitMin",
L"Tile_RedstoneDustLitMax",
L"Tile_StemMin",
L"Tile_StemMax",
L"Tile_WaterLily",
L"Sky_Dawn_Dark",
L"Sky_Dawn_Bright",
L"Material_None",
L"Material_Grass",
L"Material_Sand",
L"Material_Cloth",
L"Material_Fire",
L"Material_Ice",
L"Material_Metal",
L"Material_Plant",
L"Material_Snow",
L"Material_Clay",
L"Material_Dirt",
L"Material_Stone",
L"Material_Water",
L"Material_Wood",
L"Material_Emerald",
L"Particle_Note_00",
L"Particle_Note_01",
L"Particle_Note_02",
L"Particle_Note_03",
L"Particle_Note_04",
L"Particle_Note_05",
L"Particle_Note_06",
L"Particle_Note_07",
L"Particle_Note_08",
L"Particle_Note_09",
L"Particle_Note_10",
L"Particle_Note_11",
L"Particle_Note_12",
L"Particle_Note_13",
L"Particle_Note_14",
L"Particle_Note_15",
L"Particle_Note_16",
L"Particle_Note_17",
L"Particle_Note_18",
L"Particle_Note_19",
L"Particle_Note_20",
L"Particle_Note_21",
L"Particle_Note_22",
L"Particle_Note_23",
L"Particle_Note_24",
L"Particle_NetherPortal",
L"Particle_EnderPortal",
L"Particle_Smoke",
L"Particle_Ender",
L"Particle_Explode",
L"Particle_HugeExplosion",
L"Particle_DripWater",
L"Particle_DripLavaStart",
L"Particle_DripLavaEnd",
L"Particle_EnchantmentTable",
L"Particle_DragonBreathMin",
L"Particle_DragonBreathMax",
L"Particle_Suspend",
L"Particle_CritStart", // arrow in air
L"Particle_CritEnd", // arrow in air
L"Effect_MovementSpeed",
L"Effect_MovementSlowDown",
L"Effect_DigSpeed",
L"Effect_DigSlowdown",
L"Effect_DamageBoost",
L"Effect_Heal",
L"Effect_Harm",
L"Effect_Jump",
L"Effect_Confusion",
L"Effect_Regeneration",
L"Effect_DamageResistance",
L"Effect_FireResistance",
L"Effect_WaterBreathing",
L"Effect_Invisiblity",
L"Effect_Blindness",
L"Effect_NightVision",
L"Effect_Hunger",
L"Effect_Weakness",
L"Effect_Poison",
L"Effect_Wither",
L"Effect_HealthBoost",
L"Effect_Absorption",
L"Effect_Saturation",
L"Potion_BaseColour",
L"Mob_Creeper_Colour1",
L"Mob_Creeper_Colour2",
L"Mob_Skeleton_Colour1",
L"Mob_Skeleton_Colour2",
L"Mob_Spider_Colour1",
L"Mob_Spider_Colour2",
L"Mob_Zombie_Colour1",
L"Mob_Zombie_Colour2",
L"Mob_Slime_Colour1",
L"Mob_Slime_Colour2",
L"Mob_Ghast_Colour1",
L"Mob_Ghast_Colour2",
L"Mob_PigZombie_Colour1",
L"Mob_PigZombie_Colour2",
L"Mob_Enderman_Colour1",
L"Mob_Enderman_Colour2",
L"Mob_CaveSpider_Colour1",
L"Mob_CaveSpider_Colour2",
L"Mob_Silverfish_Colour1",
L"Mob_Silverfish_Colour2",
L"Mob_Blaze_Colour1",
L"Mob_Blaze_Colour2",
L"Mob_LavaSlime_Colour1",
L"Mob_LavaSlime_Colour2",
L"Mob_Pig_Colour1",
L"Mob_Pig_Colour2",
L"Mob_Sheep_Colour1",
L"Mob_Sheep_Colour2",
L"Mob_Cow_Colour1",
L"Mob_Cow_Colour2",
L"Mob_Chicken_Colour1",
L"Mob_Chicken_Colour2",
L"Mob_Squid_Colour1",
L"Mob_Squid_Colour2",
L"Mob_Wolf_Colour1",
L"Mob_Wolf_Colour2",
L"Mob_MushroomCow_Colour1",
L"Mob_MushroomCow_Colour2",
L"Mob_Ocelot_Colour1",
L"Mob_Ocelot_Colour2",
L"Mob_Villager_Colour1",
L"Mob_Villager_Colour2",
L"Mob_Bat_Colour1",
L"Mob_Bat_Colour2",
L"Mob_Witch_Colour1",
L"Mob_Witch_Colour2",
L"Mob_Horse_Colour1",
L"Mob_Horse_Colour2",
L"Armour_Default_Leather_Colour",
L"Under_Water_Clear_Colour",
L"Under_Lava_Clear_Colour",
L"In_Cloud_Base_Colour",
L"Under_Water_Fog_Colour",
L"Under_Lava_Fog_Colour",
L"In_Cloud_Fog_Colour",
L"Default_Fog_Colour",
L"Nether_Fog_Colour",
L"End_Fog_Colour",
L"Sign_Text",
L"Map_Text",
L"Leash_Light_Colour",
L"Leash_Dark_Colour",
L"Fire_Overlay",
L"HTMLColor_0",
L"HTMLColor_1",
L"HTMLColor_2",
L"HTMLColor_3",
L"HTMLColor_4",
L"HTMLColor_5",
L"HTMLColor_6",
L"HTMLColor_7",
L"HTMLColor_8",
L"HTMLColor_9",
L"HTMLColor_a",
L"HTMLColor_b",
L"HTMLColor_c",
L"HTMLColor_d",
L"HTMLColor_e",
L"HTMLColor_f",
L"HTMLColor_dark_0",
L"HTMLColor_dark_1",
L"HTMLColor_dark_2",
L"HTMLColor_dark_3",
L"HTMLColor_dark_4",
L"HTMLColor_dark_5",
L"HTMLColor_dark_6",
L"HTMLColor_dark_7",
L"HTMLColor_dark_8",
L"HTMLColor_dark_9",
L"HTMLColor_dark_a",
L"HTMLColor_dark_b",
L"HTMLColor_dark_c",
L"HTMLColor_dark_d",
L"HTMLColor_dark_e",
L"HTMLColor_dark_f",
L"HTMLColor_T1",
L"HTMLColor_T2",
L"HTMLColor_T3",
L"HTMLColor_Black",
L"HTMLColor_White",
L"Color_EnchantText",
L"Color_EnchantTextFocus",
L"Color_EnchantTextDisabled",
L"Color_RenamedItemTitle",
};
void ColourTable::staticCtor() {
for (unsigned int i = eMinecraftColour_NOT_SET; i < eMinecraftColour_COUNT;
++i) {
s_colourNamesMap.insert(
std::unordered_map<std::wstring, eMinecraftColour>::value_type(
ColourTableElements[i], (eMinecraftColour)i));
}
}
ColourTable::ColourTable(std::uint8_t* pbData, std::uint32_t dataLength) {
loadColoursFromData(pbData, dataLength);
}
ColourTable::ColourTable(ColourTable* defaultColours, std::uint8_t* pbData,
std::uint32_t dataLength) {
// 4J Stu - Default the colours that of the table passed in
memcpy((void*)m_colourValues, (void*)defaultColours->m_colourValues,
sizeof(int) * eMinecraftColour_COUNT);
loadColoursFromData(pbData, dataLength);
}
void ColourTable::loadColoursFromData(std::uint8_t* pbData,
std::uint32_t dataLength) {
std::vector<uint8_t> src(pbData, pbData + dataLength);
ByteArrayInputStream bais(src);
DataInputStream dis(&bais);
int versionNumber = dis.readInt();
int coloursCount = dis.readInt();
for (int i = 0; i < coloursCount; ++i) {
std::wstring colourId = dis.readUTF();
int colourValue = dis.readInt();
setColour(colourId, colourValue);
auto it = s_colourNamesMap.find(colourId);
}
bais.reset();
}
void ColourTable::setColour(const std::wstring& colourName, int value) {
auto it = s_colourNamesMap.find(colourName);
if (it != s_colourNamesMap.end()) {
m_colourValues[(int)it->second] = value;
}
}
void ColourTable::setColour(const std::wstring& colourName,
const std::wstring& value) {
setColour(colourName, _fromHEXString<int>(value));
}
unsigned int ColourTable::getColour(eMinecraftColour id) {
return m_colourValues[(int)id];
}
@@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#include <string>
#include <unordered_map>
#include "app/common/App_enums.h"
class ColourTable {
private:
unsigned int m_colourValues[eMinecraftColour_COUNT];
static const wchar_t* ColourTableElements[eMinecraftColour_COUNT];
static std::unordered_map<std::wstring, eMinecraftColour> s_colourNamesMap;
public:
static void staticCtor();
ColourTable(std::uint8_t* pbData, std::uint32_t dataLength);
ColourTable(ColourTable* defaultColours, std::uint8_t* pbData,
std::uint32_t dataLength);
unsigned int getColour(eMinecraftColour id);
unsigned int getColor(eMinecraftColour id) { return getColour(id); }
void loadColoursFromData(std::uint8_t* pbData, std::uint32_t dataLength);
void setColour(const std::wstring& colourName, int value);
void setColour(const std::wstring& colourName, const std::wstring& value);
};
@@ -0,0 +1,13 @@
#include "ConsoleGameMode.h"
#include "app/common/src/Tutorial/Tutorial.h"
#include "app/common/src/Tutorial/TutorialMode.h"
class ClientConnection;
class Minecraft;
ConsoleGameMode::ConsoleGameMode(int iPad, Minecraft* minecraft,
ClientConnection* connection)
: TutorialMode(iPad, minecraft, connection) {
tutorial = new Tutorial(iPad);
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include "app/common/src/Tutorial/TutorialMode.h"
class ClientConnection;
class Minecraft;
class ConsoleGameMode : public TutorialMode {
public:
ConsoleGameMode(int iPad, Minecraft* minecraft,
ClientConnection* connection);
virtual bool isImplemented() { return true; }
};
@@ -0,0 +1,69 @@
#pragma once
enum eAward {
eAward_TakingInventory = 0,
eAward_GettingWood,
eAward_Benchmarking,
eAward_TimeToMine,
eAward_HotTopic,
eAward_AquireHardware,
eAward_TimeToFarm,
eAward_BakeBread,
eAward_TheLie,
eAward_GettingAnUpgrade,
eAward_DeliciousFish,
eAward_OnARail,
eAward_TimeToStrike,
eAward_MonsterHunter,
eAward_CowTipper,
eAward_WhenPigsFly,
eAward_LeaderOfThePack,
eAward_MOARTools,
eAward_DispenseWithThis,
eAward_InToTheNether,
eAward_mine100Blocks,
eAward_kill10Creepers,
eAward_eatPorkChop,
eAward_play100Days,
eAward_arrowKillCreeper,
eAward_socialPost,
// 4J Stu - Does not map to any Xbox achievements
eAward_snipeSkeleton,
eAward_diamonds,
eAward_portal,
eAward_ghast,
eAward_blazeRod,
eAward_potion,
eAward_theEnd,
eAward_winGame,
eAward_enchantments,
eAward_overkill,
eAward_bookcase,
#if defined(_EXTENDED_ACHIEVEMENTS)
eAward_adventuringTime,
eAward_repopulation,
// eAward_porkChop,
eAward_diamondsToYou,
// eAward_passingTheTime,
// eAward_archer,
eAward_theHaggler,
eAward_potPlanter,
eAward_itsASign,
eAward_ironBelly,
eAward_haveAShearfulDay,
eAward_rainbowCollection,
eAward_stayinFrosty,
eAward_chestfulOfCobblestone,
eAward_renewableEnergy,
eAward_musicToMyEars,
eAward_bodyGuard,
eAward_ironMan,
eAward_zombieDoctor,
eAward_lionTamer,
#endif
eAward_Max,
};
@@ -0,0 +1,40 @@
#pragma once
enum eDebugSetting {
eDebugSetting_LoadSavesFromDisk,
eDebugSetting_WriteSavesToDisk,
eDebugSetting_FreezePlayers, // eDebugSetting_InterfaceOff,
eDebugSetting_Safearea,
eDebugSetting_MobsDontAttack,
eDebugSetting_FreezeTime,
eDebugSetting_DisableWeather,
eDebugSetting_CraftAnything,
eDebugSetting_UseDpadForDebug,
eDebugSetting_MobsDontTick,
eDebugSetting_ArtTools, // eDebugSetting_InstantDestroy,
eDebugSetting_ShowUIConsole,
eDebugSetting_DistributableSave,
eDebugSetting_DebugLeaderboards,
eDebugSetting_EnableHeightWaterOverride, // eDebugSetting_TipsAlwaysOn,
eDebugSetting_SuperflatNether,
// eDebugSetting_LightDarkBackground,
eDebugSetting_RegularLightning,
eDebugSetting_EnableBiomeOverride, // eDebugSetting_GoToNether,
// eDebugSetting_GoToEnd,
eDebugSetting_GoToOverworld,
eDebugSetting_UnlockAllDLC, // eDebugSetting_ToggleFont,
eDebugSetting_ShowUIMarketingGuide,
eDebugSetting_Max,
};
enum eDebugButton {
eDebugButton_Theme = 0,
eDebugButton_Avatar_Item_1,
eDebugButton_Avatar_Item_2,
eDebugButton_Avatar_Item_3,
eDebugButton_Gamerpic_1,
eDebugButton_Gamerpic_2,
eDebugButton_CheckTips,
eDebugButton_WipeLeaderboards,
eDebugButton_Max,
};
+267
View File
@@ -0,0 +1,267 @@
#include "DLCAudioFile.h"
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <unordered_map>
#include "platform/sdl2/Render.h"
#include "platform/sdl2/Storage.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/linux/Linux_App.h"
#include "app/include/XboxStubs.h"
#if defined(_WINDOWS64)
#include "app/windows/XML/ATGXmlParser.h"
#include "app/windows/XML/xmlFilesCallback.h"
#endif
namespace {
constexpr std::size_t AUDIO_DLC_WCHAR_BIN_SIZE = 2;
#if WCHAR_MAX > 0xFFFF
static std::wstring ReadAudioDlcWString(const void* data) {
const std::uint16_t* chars = static_cast<const std::uint16_t*>(data);
const std::uint16_t* end = chars;
while (*end != 0) {
++end;
}
std::wstring out(static_cast<std::size_t>(end - chars), 0);
for (std::size_t i = 0; i < out.size(); ++i) {
out[i] = static_cast<wchar_t>(chars[i]);
}
return out;
}
#else
static std::wstring ReadAudioDlcWString(const void* data) {
return std::wstring(static_cast<const wchar_t*>(data));
}
#endif
template <typename T>
T ReadAudioDlcValue(const std::uint8_t* data, unsigned int offset = 0) {
T value;
std::memcpy(&value, data + offset, sizeof(value));
return value;
}
template <typename T>
void ReadAudioDlcStruct(T* out, const std::uint8_t* data,
unsigned int offset = 0) {
std::memcpy(out, data + offset, sizeof(*out));
}
inline unsigned int AudioParamAdvance(unsigned int wcharCount) {
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_PARAM) +
wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
}
inline unsigned int AudioDetailAdvance(unsigned int wcharCount) {
return static_cast<unsigned int>(sizeof(C4JStorage::DLC_FILE_DETAILS) +
wcharCount * AUDIO_DLC_WCHAR_BIN_SIZE);
}
inline std::wstring ReadAudioParamString(const std::uint8_t* data,
unsigned int offset) {
return ReadAudioDlcWString(data + offset +
offsetof(C4JStorage::DLC_FILE_PARAM, wchData));
}
} // namespace
DLCAudioFile::DLCAudioFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_Audio, path) {
m_pbData = nullptr;
m_dataBytes = 0;
}
void DLCAudioFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes) {
m_pbData = pbData;
m_dataBytes = dataBytes;
processDLCDataFile(pbData, dataBytes);
}
std::uint8_t* DLCAudioFile::getData(std::uint32_t& dataBytes) {
dataBytes = m_dataBytes;
return m_pbData;
}
const wchar_t* DLCAudioFile::wchTypeNamesA[] = {
L"CUENAME",
L"CREDIT",
};
DLCAudioFile::EAudioParameterType DLCAudioFile::getParameterType(
const std::wstring& paramName) {
EAudioParameterType type = e_AudioParamType_Invalid;
for (int i = 0; i < e_AudioParamType_Max; ++i) {
if (paramName.compare(wchTypeNamesA[i]) == 0) {
type = (EAudioParameterType)i;
break;
}
}
return type;
}
void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype,
const std::wstring& value) {
switch (ptype) {
case e_AudioParamType_Credit: // If this parameter exists, then mark
// this as free
// add it to the DLC credits list
// we'll need to justify this text since we don't have a lot of room
// for lines of credits
{
// don't look for duplicate in the music credits
// if(app.AlreadySeenCreditText(value)) break;
int maximumChars = 55;
bool bIsSDMode =
!RenderManager.IsHiDef() && !RenderManager.IsWidescreen();
if (bIsSDMode) {
maximumChars = 45;
}
switch (XGetLanguage()) {
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
maximumChars = 35;
break;
}
std::wstring creditValue = value;
while (creditValue.length() > maximumChars) {
unsigned int i = 1;
while (i < creditValue.length() &&
(i + 1) <= maximumChars) {
i++;
}
int iLast = (int)creditValue.find_last_of(L" ", i);
switch (XGetLanguage()) {
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
iLast = maximumChars;
break;
default:
iLast = (int)creditValue.find_last_of(L" ", i);
break;
}
// if a space was found, include the space on this line
if (iLast != i) {
iLast++;
}
app.AddCreditText((creditValue.substr(0, iLast)).c_str());
creditValue = creditValue.substr(iLast);
}
app.AddCreditText(creditValue.c_str());
}
break;
case e_AudioParamType_Cuename:
m_parameters[type].push_back(value);
// m_parameters[(int)type] = value;
break;
default:
break;
}
}
bool DLCAudioFile::processDLCDataFile(std::uint8_t* pbData,
std::uint32_t dataLength) {
std::unordered_map<int, EAudioParameterType> parameterMapping;
unsigned int uiCurrentByte = 0;
// File format defined in the AudioPacker
// File format: Version 1
unsigned int uiVersion =
ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
if (uiVersion < CURRENT_AUDIO_VERSION_NUM) {
if (pbData != nullptr) delete[] pbData;
app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion);
return false;
}
unsigned int uiParameterTypeCount =
ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_PARAM paramBuf;
ReadAudioDlcStruct(&paramBuf, pbData, uiCurrentByte);
for (unsigned int i = 0; i < uiParameterTypeCount; i++) {
// Map DLC strings to application strings, then store the DLC index
// mapping to application index
std::wstring parameterName =
ReadAudioParamString(pbData, uiCurrentByte);
EAudioParameterType type = getParameterType(parameterName);
if (type != e_AudioParamType_Invalid) {
parameterMapping[paramBuf.dwType] = type;
}
uiCurrentByte += AudioParamAdvance(paramBuf.dwWchCount);
ReadAudioDlcStruct(&paramBuf, pbData, uiCurrentByte);
}
unsigned int uiFileCount =
ReadAudioDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_DETAILS fileBuf;
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
unsigned int tempByteOffset = uiCurrentByte;
for (unsigned int i = 0; i < uiFileCount; i++) {
tempByteOffset += AudioDetailAdvance(fileBuf.dwWchCount);
ReadAudioDlcStruct(&fileBuf, pbData, tempByteOffset);
}
std::uint8_t* pbTemp = &pbData[tempByteOffset];
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
for (unsigned int i = 0; i < uiFileCount; i++) {
EAudioType type = (EAudioType)fileBuf.dwType;
// Params
unsigned int uiParameterCount = ReadAudioDlcValue<unsigned int>(pbTemp);
pbTemp += sizeof(int);
ReadAudioDlcStruct(&paramBuf, pbTemp);
for (unsigned int j = 0; j < uiParameterCount; j++) {
// EAudioParameterType paramType = e_AudioParamType_Invalid;
auto it = parameterMapping.find(paramBuf.dwType);
if (it != parameterMapping.end()) {
addParameter(type, (EAudioParameterType)paramBuf.dwType,
ReadAudioParamString(pbTemp, 0));
}
pbTemp += AudioParamAdvance(paramBuf.dwWchCount);
ReadAudioDlcStruct(&paramBuf, pbTemp);
}
// Move the pointer to the start of the next files data;
pbTemp += fileBuf.uiFileSize;
uiCurrentByte += AudioDetailAdvance(fileBuf.dwWchCount);
ReadAudioDlcStruct(&fileBuf, pbData, uiCurrentByte);
}
return true;
}
int DLCAudioFile::GetCountofType(DLCAudioFile::EAudioType eType) {
return m_parameters[eType].size();
}
std::wstring& DLCAudioFile::GetSoundName(int iIndex) {
int iWorldType = e_AudioType_Overworld;
while (iIndex >= m_parameters[iWorldType].size()) {
iIndex -= m_parameters[iWorldType].size();
iWorldType++;
}
return m_parameters[iWorldType].at(iIndex);
}
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "DLCFile.h"
class DLCAudioFile : public DLCFile {
public:
// If you add to the Enum,then you need to add the array of type names
// These are the names used in the XML for the parameters
enum EAudioType {
e_AudioType_Invalid = -1,
e_AudioType_Overworld = 0,
e_AudioType_Nether,
e_AudioType_End,
e_AudioType_Max,
};
enum EAudioParameterType {
e_AudioParamType_Invalid = -1,
e_AudioParamType_Cuename = 0,
e_AudioParamType_Credit,
e_AudioParamType_Max,
};
static const wchar_t* wchTypeNamesA[e_AudioParamType_Max];
DLCAudioFile(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
virtual std::uint8_t* getData(std::uint32_t& dataBytes);
bool processDLCDataFile(std::uint8_t* pbData, std::uint32_t dataLength);
int GetCountofType(DLCAudioFile::EAudioType ptype);
std::wstring& GetSoundName(int iIndex);
private:
using DLCFile::addParameter;
std::uint8_t* m_pbData;
std::uint32_t m_dataBytes;
static const int CURRENT_AUDIO_VERSION_NUM = 1;
// std::unordered_map<int, std::wstring> m_parameters;
std::vector<std::wstring> m_parameters[e_AudioType_Max];
// use the EAudioType to order these
void addParameter(DLCAudioFile::EAudioType type,
DLCAudioFile::EAudioParameterType ptype,
const std::wstring& value);
DLCAudioFile::EAudioParameterType getParameterType(
const std::wstring& paramName);
};
@@ -0,0 +1,12 @@
#include "DLCCapeFile.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/linux/Linux_App.h"
DLCCapeFile::DLCCapeFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_Cape, path) {}
void DLCCapeFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes) {
app.AddMemoryTextureFile(m_path, pbData, dataBytes);
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCFile.h"
class DLCCapeFile : public DLCFile {
public:
DLCCapeFile(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
};
@@ -0,0 +1,28 @@
#include "DLCColourTableFile.h"
#include "DLCManager.h"
#include "app/common/src/Colours/ColourTable.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/linux/Linux_App.h"
#include "minecraft/client/Minecraft.h"
#include "minecraft/client/skins/TexturePack.h"
#include "minecraft/client/skins/TexturePackRepository.h"
DLCColourTableFile::DLCColourTableFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_ColourTable, path) {
m_colourTable = nullptr;
}
DLCColourTableFile::~DLCColourTableFile() {
if (m_colourTable != nullptr) {
app.DebugPrintf("Deleting DLCColourTableFile data\n");
delete m_colourTable;
}
}
void DLCColourTableFile::addData(std::uint8_t* pbData,
std::uint32_t dataBytes) {
ColourTable* defaultColourTable =
Minecraft::GetInstance()->skins->getDefault()->getColourTable();
m_colourTable = new ColourTable(defaultColourTable, pbData, dataBytes);
}
@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCFile.h"
class ColourTable;
class DLCColourTableFile : public DLCFile {
private:
ColourTable* m_colourTable;
public:
DLCColourTableFile(const std::wstring& path);
~DLCColourTableFile();
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
ColourTable* getColourTable() { return m_colourTable; }
};
+26
View File
@@ -0,0 +1,26 @@
#include "DLCFile.h"
#include <sstream>
#include "app/common/Minecraft_Macros.h"
#include "app/common/src/DLC/DLCManager.h"
DLCFile::DLCFile(DLCManager::EDLCType type, const std::wstring& path) {
m_type = type;
m_path = path;
// store the id
bool dlcSkin = path.substr(0, 3).compare(L"dlc") == 0;
if (dlcSkin) {
std::wstring skinValue = path.substr(7, path.size());
skinValue = skinValue.substr(0, skinValue.find_first_of(L'.'));
std::wstringstream ss;
ss << std::dec << skinValue.c_str();
ss >> m_dwSkinId;
m_dwSkinId = MAKE_SKIN_BITMASK(true, m_dwSkinId);
} else {
m_dwSkinId = 0;
}
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCManager.h"
class DLCFile {
protected:
DLCManager::EDLCType m_type;
std::wstring m_path;
std::uint32_t m_dwSkinId;
public:
DLCFile(DLCManager::EDLCType type, const std::wstring& path);
virtual ~DLCFile() {}
DLCManager::EDLCType getType() { return m_type; }
std::wstring getPath() { return m_path; }
std::uint32_t getSkinID() { return m_dwSkinId; }
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes) {}
virtual std::uint8_t* getData(std::uint32_t& dataBytes) {
dataBytes = 0;
return nullptr;
}
virtual void addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value) {}
virtual std::wstring getParameterAsString(
DLCManager::EDLCParameterType type) {
return L"";
}
virtual bool getParameterAsBool(DLCManager::EDLCParameterType type) {
return false;
}
};
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include "DLCFile.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerationOptions.h"
class DLCGameRules : public DLCFile {
public:
DLCGameRules(DLCManager::EDLCType type, const std::wstring& path)
: DLCFile(type, path) {}
};
@@ -0,0 +1,20 @@
#include "DLCGameRulesFile.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCGameRules.h"
DLCGameRulesFile::DLCGameRulesFile(const std::wstring& path)
: DLCGameRules(DLCManager::e_DLCType_GameRules, path) {
m_pbData = nullptr;
m_dataBytes = 0;
}
void DLCGameRulesFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes) {
m_pbData = pbData;
m_dataBytes = dataBytes;
}
std::uint8_t* DLCGameRulesFile::getData(std::uint32_t& dataBytes) {
dataBytes = m_dataBytes;
return m_pbData;
}
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCGameRules.h"
class DLCGameRulesFile : public DLCGameRules {
private:
std::uint8_t* m_pbData;
std::uint32_t m_dataBytes;
public:
DLCGameRulesFile(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
virtual std::uint8_t* getData(std::uint32_t& dataBytes);
};
@@ -0,0 +1,44 @@
#include "DLCGameRulesHeader.h"
#include <string>
#include "DLCManager.h"
#include "app/common/src/DLC/DLCGameRules.h"
#include "app/common/src/GameRules/GameRuleManager.h"
#include "app/linux/Linux_App.h"
class StringTable;
DLCGameRulesHeader::DLCGameRulesHeader(const std::wstring& path)
: DLCGameRules(DLCManager::e_DLCType_GameRulesHeader, path) {
m_pbData = nullptr;
m_dataBytes = 0;
m_hasData = false;
m_grfPath = path.substr(0, path.length() - 4) + L".grf";
lgo = nullptr;
}
void DLCGameRulesHeader::addData(std::uint8_t* pbData,
std::uint32_t dataBytes) {
m_pbData = pbData;
m_dataBytes = dataBytes;
}
std::uint8_t* DLCGameRulesHeader::getData(std::uint32_t& dataBytes) {
dataBytes = m_dataBytes;
return m_pbData;
}
void DLCGameRulesHeader::setGrfData(std::uint8_t* fData, std::uint32_t dataSize,
StringTable* st) {
if (!m_hasData) {
m_hasData = true;
// app.m_gameRules.loadGameRules(lgo, fData, fSize);
app.m_gameRules.readRuleFile(lgo, fData, dataSize, st);
}
}
@@ -0,0 +1,51 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCGameRules.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerationOptions.h"
class StringTable;
class DLCGameRulesHeader : public DLCGameRules, public JustGrSource {
private:
// GR-Header
std::uint8_t* m_pbData;
std::uint32_t m_dataBytes;
bool m_hasData;
public:
virtual bool requiresTexturePack() { return m_bRequiresTexturePack; }
virtual std::uint32_t getRequiredTexturePackId() {
return m_requiredTexturePackId;
}
virtual std::wstring getDefaultSaveName() { return m_defaultSaveName; }
virtual const wchar_t* getWorldName() { return m_worldName.c_str(); }
virtual const wchar_t* getDisplayName() { return m_displayName.c_str(); }
virtual std::wstring getGrfPath() { return L"GameRules.grf"; }
virtual void setRequiresTexturePack(bool x) { m_bRequiresTexturePack = x; }
virtual void setRequiredTexturePackId(std::uint32_t x) {
m_requiredTexturePackId = x;
}
virtual void setDefaultSaveName(const std::wstring& x) {
m_defaultSaveName = x;
}
virtual void setWorldName(const std::wstring& x) { m_worldName = x; }
virtual void setDisplayName(const std::wstring& x) { m_displayName = x; }
virtual void setGrfPath(const std::wstring& x) { m_grfPath = x; }
LevelGenerationOptions* lgo;
public:
DLCGameRulesHeader(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
virtual std::uint8_t* getData(std::uint32_t& dataBytes);
void setGrfData(std::uint8_t* fData, std::uint32_t dataSize, StringTable*);
virtual bool ready() { return m_hasData; }
};
@@ -0,0 +1,15 @@
#include "DLCLocalisationFile.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/common/src/Localisation/StringTable.h"
DLCLocalisationFile::DLCLocalisationFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_LocalisationData, path) {
m_strings = nullptr;
}
void DLCLocalisationFile::addData(std::uint8_t* pbData,
std::uint32_t dataBytes) {
m_strings = new StringTable(pbData, dataBytes);
}
@@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCFile.h"
class StringTable;
class DLCLocalisationFile : public DLCFile {
private:
StringTable* m_strings;
public:
DLCLocalisationFile(const std::wstring& path);
DLCLocalisationFile(
std::uint8_t* pbData,
std::uint32_t dataBytes); // when we load in a texture pack details
// file from TMS++
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
StringTable* getStringTable() { return m_strings; }
};
+732
View File
@@ -0,0 +1,732 @@
#include "DLCManager.h"
#include <wchar.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <limits>
#include <sstream>
#include <unordered_map>
#include <utility>
#include "platform/sdl2/Profile.h"
#include "platform/sdl2/Storage.h"
#include "DLCFile.h"
#include "DLCPack.h"
#include "app/common/src/GameRules/GameRuleManager.h"
#include "app/linux/Linux_App.h"
#include "app/linux/Linux_UIController.h"
#include "console_helpers/PortableFileIO.h"
#include "console_helpers/StringHelpers.h"
#include "minecraft/client/Minecraft.h"
#include "minecraft/client/skins/TexturePackRepository.h"
#include "strings.h"
// 4jcraft, this is the size of wchar_t on disk
// the DLC was created on windows, with wchar_t beeing 2 bytes and UTF-16
static const std::size_t DLC_WCHAR_BIN_SIZE = 2;
#if WCHAR_MAX > 0xFFFF
// than sizeof(wchar_t) != DLC_WCHAR_BIN_SIZE
// e.g. Linux and all Posix/Unix systems with wchar_t beeing 4B/32bit
static_assert(sizeof(wchar_t) == 4,
"wchar_t is not 4bytes but larger than 2bytes ???");
static inline std::wstring dlc_read_wstring(const void* data) {
const std::uint16_t* p = static_cast<const std::uint16_t*>(data);
// find the end (nullterminated)
const std::uint16_t* end = p;
while (*end) {
++end;
}
std::size_t len = static_cast<std::size_t>(end - p);
// allocate wstring with length len
// it will be nullterminated internally, do not worry.
std::wstring out(len, 0);
// and copy them into thje string
for (std::size_t i = 0; i < len; ++i) {
out[i] = static_cast<wchar_t>(p[i]);
}
return out;
}
#define DLC_WSTRING(ptr) dlc_read_wstring(ptr)
#else
// just in case.
static_assert(sizeof(wchar_t) == 2,
"How did we get here? wide char smaller than 2 bytes");
// perfectly fine scince wchar_t will be 2 bytes (UCS-2/UTF-16)
#define DLC_WSTRING(ptr) std::wstring((wchar_t*)(ptr))
#endif
#define DLC_PARAM_ADV(n) \
(sizeof(C4JStorage::DLC_FILE_PARAM) + (n) * DLC_WCHAR_BIN_SIZE)
#define DLC_DETAIL_ADV(n) \
(sizeof(C4JStorage::DLC_FILE_DETAILS) + (n) * DLC_WCHAR_BIN_SIZE)
namespace {
template <typename T>
T ReadDlcValue(const std::uint8_t* data, unsigned int offset = 0) {
T value;
std::memcpy(&value, data + offset, sizeof(value));
return value;
}
template <typename T>
void ReadDlcStruct(T* out, const std::uint8_t* data, unsigned int offset = 0) {
std::memcpy(out, data + offset, sizeof(*out));
}
std::wstring getMountedDlcReadPath(const std::string& path) {
std::wstring readPath = convStringToWstring(path);
#if defined(_WINDOWS64)
const std::string mountedPath = StorageManager.GetMountedPath(path.c_str());
if (!mountedPath.empty()) {
readPath = convStringToWstring(mountedPath);
}
#endif
return readPath;
}
bool readOwnedDlcFile(const std::string& path, std::uint8_t** ppData,
unsigned int* pBytesRead) {
*ppData = nullptr;
*pBytesRead = 0;
const std::wstring readPath = getMountedDlcReadPath(path);
std::FILE* file = PortableFileIO::OpenBinaryFileForRead(readPath);
if (file == nullptr) {
return false;
}
if (!PortableFileIO::Seek(file, 0, SEEK_END)) {
std::fclose(file);
return false;
}
const int64_t endPosition = PortableFileIO::Tell(file);
if (endPosition <= 0 ||
endPosition > std::numeric_limits<unsigned int>::max()) {
std::fclose(file);
return false;
}
const unsigned int fileSize = static_cast<unsigned int>(endPosition);
if (!PortableFileIO::Seek(file, 0, SEEK_SET)) {
std::fclose(file);
return false;
}
std::uint8_t* data = new std::uint8_t[fileSize];
const std::size_t bytesRead = std::fread(data, 1, fileSize, file);
const bool failed = std::ferror(file) != 0 || bytesRead != fileSize;
std::fclose(file);
if (failed) {
delete[] data;
return false;
}
*ppData = data;
*pBytesRead = static_cast<unsigned int>(bytesRead);
return true;
}
} // namespace
const wchar_t* DLCManager::wchTypeNamesA[] = {
L"DISPLAYNAME",
L"THEMENAME",
L"FREE",
L"CREDIT",
L"CAPEPATH",
L"BOX",
L"ANIM",
L"PACKID",
L"NETHERPARTICLECOLOUR",
L"ENCHANTTEXTCOLOUR",
L"ENCHANTTEXTFOCUSCOLOUR",
L"DATAPATH",
L"PACKVERSION",
};
DLCManager::DLCManager() {
// m_bNeedsUpdated = true;
m_bNeedsCorruptCheck = true;
}
DLCManager::~DLCManager() {
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = *it;
delete pack;
}
}
DLCManager::EDLCParameterType DLCManager::getParameterType(
const std::wstring& paramName) {
EDLCParameterType type = e_DLCParamType_Invalid;
for (unsigned int i = 0; i < e_DLCParamType_Max; ++i) {
if (paramName.compare(wchTypeNamesA[i]) == 0) {
type = (EDLCParameterType)i;
break;
}
}
return type;
}
unsigned int DLCManager::getPackCount(EDLCType type /*= e_DLCType_All*/) {
unsigned int packCount = 0;
if (type != e_DLCType_All) {
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = *it;
if (pack->getDLCItemsCount(type) > 0) {
++packCount;
}
}
} else {
packCount = static_cast<unsigned int>(m_packs.size());
}
return packCount;
}
void DLCManager::addPack(DLCPack* pack) { m_packs.push_back(pack); }
void DLCManager::removePack(DLCPack* pack) {
if (pack != nullptr) {
auto it = find(m_packs.begin(), m_packs.end(), pack);
if (it != m_packs.end()) m_packs.erase(it);
delete pack;
}
}
void DLCManager::removeAllPacks(void) {
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = (DLCPack*)*it;
delete pack;
}
m_packs.clear();
}
void DLCManager::LanguageChanged(void) {
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = (DLCPack*)*it;
// update the language
pack->UpdateLanguage();
}
}
DLCPack* DLCManager::getPack(const std::wstring& name) {
DLCPack* pack = nullptr;
// uint32_t currentIndex = 0;
DLCPack* currentPack = nullptr;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
currentPack = *it;
std::wstring wsName = currentPack->getName();
if (wsName.compare(name) == 0) {
pack = currentPack;
break;
}
}
return pack;
}
DLCPack* DLCManager::getPack(unsigned int index,
EDLCType type /*= e_DLCType_All*/) {
DLCPack* pack = nullptr;
if (type != e_DLCType_All) {
unsigned int currentIndex = 0;
DLCPack* currentPack = nullptr;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
currentPack = *it;
if (currentPack->getDLCItemsCount(type) > 0) {
if (currentIndex == index) {
pack = currentPack;
break;
}
++currentIndex;
}
}
} else {
if (index >= m_packs.size()) {
app.DebugPrintf(
"DLCManager: Trying to access a DLC pack beyond the range of "
"valid packs\n");
assert(0);
}
pack = m_packs[index];
}
return pack;
}
unsigned int DLCManager::getPackIndex(DLCPack* pack, bool& found,
EDLCType type /*= e_DLCType_All*/) {
unsigned int foundIndex = 0;
found = false;
if (pack == nullptr) {
app.DebugPrintf(
"DLCManager: Attempting to find the index for a nullptr pack\n");
//__debugbreak();
return foundIndex;
}
if (type != e_DLCType_All) {
unsigned int index = 0;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* thisPack = *it;
if (thisPack->getDLCItemsCount(type) > 0) {
if (thisPack == pack) {
found = true;
foundIndex = index;
break;
}
++index;
}
}
} else {
unsigned int index = 0;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* thisPack = *it;
if (thisPack == pack) {
found = true;
foundIndex = index;
break;
}
++index;
}
}
return foundIndex;
}
unsigned int DLCManager::getPackIndexContainingSkin(const std::wstring& path,
bool& found) {
unsigned int foundIndex = 0;
found = false;
unsigned int index = 0;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = *it;
if (pack->getDLCItemsCount(e_DLCType_Skin) > 0) {
if (pack->doesPackContainSkin(path)) {
foundIndex = index;
found = true;
break;
}
++index;
}
}
return foundIndex;
}
DLCPack* DLCManager::getPackContainingSkin(const std::wstring& path) {
DLCPack* foundPack = nullptr;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = *it;
if (pack->getDLCItemsCount(e_DLCType_Skin) > 0) {
if (pack->doesPackContainSkin(path)) {
foundPack = pack;
break;
}
}
}
return foundPack;
}
DLCSkinFile* DLCManager::getSkinFile(const std::wstring& path) {
DLCSkinFile* foundSkinfile = nullptr;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
DLCPack* pack = *it;
foundSkinfile = pack->getSkinFile(path);
if (foundSkinfile != nullptr) {
break;
}
}
return foundSkinfile;
}
unsigned int DLCManager::checkForCorruptDLCAndAlert(
bool showMessage /*= true*/) {
unsigned int corruptDLCCount = m_dwUnnamedCorruptDLCCount;
DLCPack* pack = nullptr;
DLCPack* firstCorruptPack = nullptr;
for (auto it = m_packs.begin(); it != m_packs.end(); ++it) {
pack = *it;
if (pack->IsCorrupt()) {
++corruptDLCCount;
if (firstCorruptPack == nullptr) firstCorruptPack = pack;
}
}
// gotta fix this someday
if (corruptDLCCount > 0 && showMessage) {
unsigned int uiIDA[1];
uiIDA[0] = IDS_CONFIRM_OK;
if (corruptDLCCount == 1 && firstCorruptPack != nullptr) {
// pass in the pack format string
wchar_t wchFormat[132];
swprintf(wchFormat, 132, L"%ls\n\n%%ls",
firstCorruptPack->getName().c_str());
C4JStorage::EMessageResult result = ui.RequestErrorMessage(
IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC, uiIDA, 1,
ProfileManager.GetPrimaryPad(), nullptr, nullptr, wchFormat);
} else {
C4JStorage::EMessageResult result = ui.RequestErrorMessage(
IDS_CORRUPT_DLC_TITLE, IDS_CORRUPT_DLC_MULTIPLE, uiIDA, 1,
ProfileManager.GetPrimaryPad());
}
}
SetNeedsCorruptCheck(false);
return corruptDLCCount;
}
bool DLCManager::readDLCDataFile(unsigned int& dwFilesProcessed,
const std::wstring& path, DLCPack* pack,
bool fromArchive) {
return readDLCDataFile(dwFilesProcessed, wstringtofilename(path), pack,
fromArchive);
}
bool DLCManager::readDLCDataFile(unsigned int& dwFilesProcessed,
const std::string& path, DLCPack* pack,
bool fromArchive) {
std::wstring wPath = convStringToWstring(path);
if (fromArchive && app.getArchiveFileSize(wPath) >= 0) {
std::vector<uint8_t> bytes = app.getArchiveFile(wPath);
return processDLCDataFile(dwFilesProcessed, bytes.data(), bytes.size(),
pack);
} else if (fromArchive)
return false;
unsigned int bytesRead = 0;
std::uint8_t* pbData = nullptr;
if (!readOwnedDlcFile(path, &pbData, &bytesRead)) {
app.DebugPrintf("Failed to open DLC data file %s\n", path.c_str());
pack->SetIsCorrupt(true);
SetNeedsCorruptCheck(true);
return false;
}
return processDLCDataFile(dwFilesProcessed, pbData, bytesRead, pack);
}
bool DLCManager::processDLCDataFile(unsigned int& dwFilesProcessed,
std::uint8_t* pbData, unsigned int dwLength,
DLCPack* pack)
// a bunch of makros to reduce memcpy and offset boilerplate
#define DLC_READ_UINT(out, buf, off) \
memcpy((out), (buf) + (off), sizeof(unsigned int))
#define DLC_READ_PARAM(out, buf, off) \
memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_PARAM))
#define DLC_READ_DETAIL(out, buf, off) \
memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_DETAILS))
// for details, read in the function below
#define DLC_PARAM_WSTR(buf, off) \
DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_PARAM, wchData))
#define DLC_DETAIL_WSTR(buf, off) \
DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_DETAILS, wchFile))
{
std::unordered_map<int, DLCManager::EDLCParameterType> parameterMapping;
unsigned int uiCurrentByte = 0;
// File format defined in the DLC_Creator
// File format: Version 2
// unsigned long, version number
// unsigned long, t = number of parameter types
// t * DLC_FILE_PARAM structs mapping strings to id's
// unsigned long, n = number of files
// n * DLC_FILE_DETAILS describing each file in the pack
// n * files of the form
// // unsigned long, p = number of parameters
// // p * DLC_FILE_PARAM describing each parameter for this file
// // ulFileSize bytes of data blob of the file added
// 4jcraft, some parts of this code changed, specifically:
// instead of casting a goddamn raw byte pointer and dereferencing it
// use memcpy, and access WSTRING with propper offset
// (scince bufferoffset after advancing by variable string length is not
// guaranteed to be properly aligned, so casting to a scalar/struct is UB)
// those casts coult be dangerous on e.g. ARM, because it doesnt handle
// missaligned loads, like x86/x64, so it would crash
// WHO TF USES HUNGARIAN NOTATION
unsigned int uiVersion;
DLC_READ_UINT(&uiVersion, pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
if (uiVersion < CURRENT_DLC_VERSION_NUM) {
if (pbData != nullptr) delete[] pbData;
app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion);
return false;
}
pack->SetDataPointer(pbData);
// safe, offset 4, aligned
unsigned int uiParameterCount;
DLC_READ_UINT(&uiParameterCount, pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_PARAM parBuf;
DLC_READ_PARAM(&parBuf, pbData, uiCurrentByte);
// uint32_t dwwchCount=0;
for (unsigned int i = 0; i < uiParameterCount; i++) {
// Map DLC strings to application strings, then store the DLC index
// mapping to application index
std::wstring parameterName = DLC_PARAM_WSTR(pbData, uiCurrentByte);
DLCManager::EDLCParameterType type =
DLCManager::getParameterType(parameterName);
if (type != DLCManager::e_DLCParamType_Invalid) {
parameterMapping[parBuf.dwType] = type;
}
uiCurrentByte += DLC_PARAM_ADV(parBuf.dwWchCount);
DLC_READ_PARAM(&parBuf, pbData, uiCurrentByte);
}
// ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM);
unsigned int uiFileCount;
DLC_READ_UINT(&uiFileCount, pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_DETAILS fileBuf;
DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte);
unsigned int dwTemp = uiCurrentByte;
for (unsigned int i = 0; i < uiFileCount; i++) {
dwTemp += DLC_DETAIL_ADV(fileBuf.dwWchCount);
DLC_READ_DETAIL(&fileBuf, pbData, dwTemp);
}
std::uint8_t* pbTemp =
&pbData[dwTemp]; //+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount;
DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte);
for (unsigned int i = 0; i < uiFileCount; i++) {
DLCManager::EDLCType type = (DLCManager::EDLCType)fileBuf.dwType;
DLCFile* dlcFile = nullptr;
DLCPack* dlcTexturePack = nullptr;
if (type == e_DLCType_TexturePack) {
dlcTexturePack =
new DLCPack(pack->getName(), pack->getLicenseMask());
} else if (type != e_DLCType_PackConfig) {
dlcFile =
pack->addFile(type, DLC_DETAIL_WSTR(pbData, uiCurrentByte));
}
// Params
unsigned int uiParamCount;
DLC_READ_UINT(&uiParamCount, pbTemp, 0);
pbTemp += sizeof(int);
DLC_READ_PARAM(&parBuf, pbTemp, 0);
for (unsigned int j = 0; j < uiParamCount; j++) {
// DLCManager::EDLCParameterType paramType =
// DLCManager::e_DLCParamType_Invalid;
auto it = parameterMapping.find(parBuf.dwType);
if (it != parameterMapping.end()) {
if (type == e_DLCType_PackConfig) {
pack->addParameter(it->second, DLC_PARAM_WSTR(pbTemp, 0));
} else {
if (dlcFile != nullptr)
dlcFile->addParameter(it->second,
DLC_PARAM_WSTR(pbTemp, 0));
else if (dlcTexturePack != nullptr)
dlcTexturePack->addParameter(it->second,
DLC_PARAM_WSTR(pbTemp, 0));
}
}
pbTemp += DLC_PARAM_ADV(parBuf.dwWchCount);
DLC_READ_PARAM(&parBuf, pbTemp, 0);
}
// pbTemp+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM);
if (dlcTexturePack != nullptr) {
unsigned int texturePackFilesProcessed = 0;
bool validPack =
processDLCDataFile(texturePackFilesProcessed, pbTemp,
fileBuf.uiFileSize, dlcTexturePack);
pack->SetDataPointer(
nullptr); // If it's a child pack, it doesn't own the data
if (!validPack || texturePackFilesProcessed == 0) {
delete dlcTexturePack;
dlcTexturePack = nullptr;
} else {
pack->addChildPack(dlcTexturePack);
if (dlcTexturePack->getDLCItemsCount(
DLCManager::e_DLCType_Texture) > 0) {
Minecraft::GetInstance()->skins->addTexturePackFromDLC(
dlcTexturePack, dlcTexturePack->GetPackId());
}
}
++dwFilesProcessed;
} else if (dlcFile != nullptr) {
// Data
dlcFile->addData(pbTemp, fileBuf.uiFileSize);
// TODO - 4J Stu Remove the need for this vSkinNames vector, or
// manage it differently
switch (fileBuf.dwType) {
case DLCManager::e_DLCType_Skin:
app.vSkinNames.push_back(
DLC_DETAIL_WSTR(pbData, uiCurrentByte));
break;
}
++dwFilesProcessed;
}
// Move the pointer to the start of the next files data;
pbTemp += fileBuf.uiFileSize;
uiCurrentByte += DLC_DETAIL_ADV(fileBuf.dwWchCount);
DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte);
}
if (pack->getDLCItemsCount(DLCManager::e_DLCType_GameRules) > 0 ||
pack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader) > 0) {
app.m_gameRules.loadGameRules(pack);
}
if (pack->getDLCItemsCount(DLCManager::e_DLCType_Audio) > 0) {
// app.m_Audio.loadAudioDetails(pack);
}
// TODO Should be able to delete this data, but we can't yet due to how it
// is added to the Memory textures (MEM_file)
return true;
}
std::uint32_t DLCManager::retrievePackIDFromDLCDataFile(const std::string& path,
DLCPack* pack) {
std::uint32_t packId = 0;
unsigned int bytesRead = 0;
std::uint8_t* pbData = nullptr;
if (!readOwnedDlcFile(path, &pbData, &bytesRead)) {
return 0;
}
packId = retrievePackID(pbData, bytesRead, pack);
delete[] pbData;
return packId;
}
std::uint32_t DLCManager::retrievePackID(std::uint8_t* pbData,
unsigned int dwLength, DLCPack* pack) {
std::uint32_t packId = 0;
bool bPackIDSet = false;
std::unordered_map<int, DLCManager::EDLCParameterType> parameterMapping;
unsigned int uiCurrentByte = 0;
// File format defined in the DLC_Creator
// File format: Version 2
// unsigned long, version number
// unsigned long, t = number of parameter types
// t * DLC_FILE_PARAM structs mapping strings to id's
// unsigned long, n = number of files
// n * DLC_FILE_DETAILS describing each file in the pack
// n * files of the form
// // unsigned long, p = number of parameters
// // p * DLC_FILE_PARAM describing each parameter for this file
// // ulFileSize bytes of data blob of the file added
unsigned int uiVersion = ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
if (uiVersion < CURRENT_DLC_VERSION_NUM) {
app.DebugPrintf("DLC version of %d is too old to be read\n", uiVersion);
return 0;
}
pack->SetDataPointer(pbData);
unsigned int uiParameterCount =
ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_PARAM paramBuf;
ReadDlcStruct(&paramBuf, pbData, uiCurrentByte);
for (unsigned int i = 0; i < uiParameterCount; i++) {
// Map DLC strings to application strings, then store the DLC index
// mapping to application index
std::wstring parameterName = DLC_PARAM_WSTR(pbData, uiCurrentByte);
DLCManager::EDLCParameterType type =
DLCManager::getParameterType(parameterName);
if (type != DLCManager::e_DLCParamType_Invalid) {
parameterMapping[paramBuf.dwType] = type;
}
uiCurrentByte += DLC_PARAM_ADV(paramBuf.dwWchCount);
ReadDlcStruct(&paramBuf, pbData, uiCurrentByte);
}
unsigned int uiFileCount =
ReadDlcValue<unsigned int>(pbData, uiCurrentByte);
uiCurrentByte += sizeof(int);
C4JStorage::DLC_FILE_DETAILS fileBuf;
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
unsigned int dwTemp = uiCurrentByte;
for (unsigned int i = 0; i < uiFileCount; i++) {
dwTemp += DLC_DETAIL_ADV(fileBuf.dwWchCount);
ReadDlcStruct(&fileBuf, pbData, dwTemp);
}
std::uint8_t* pbTemp = &pbData[dwTemp];
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
for (unsigned int i = 0; i < uiFileCount; i++) {
DLCManager::EDLCType type = (DLCManager::EDLCType)fileBuf.dwType;
// Params
uiParameterCount = ReadDlcValue<unsigned int>(pbTemp);
pbTemp += sizeof(int);
ReadDlcStruct(&paramBuf, pbTemp);
for (unsigned int j = 0; j < uiParameterCount; j++) {
auto it = parameterMapping.find(paramBuf.dwType);
if (it != parameterMapping.end()) {
if (type == e_DLCType_PackConfig) {
if (it->second == e_DLCParamType_PackId) {
std::wstring wsTemp = DLC_PARAM_WSTR(pbTemp, 0);
std::wstringstream ss;
// 4J Stu - numbered using decimal to make it easier for
// artists/people to number manually
ss << std::dec << wsTemp.c_str();
ss >> packId;
bPackIDSet = true;
break;
}
}
}
pbTemp += DLC_PARAM_ADV(paramBuf.dwWchCount);
ReadDlcStruct(&paramBuf, pbTemp);
}
if (bPackIDSet) break;
// Move the pointer to the start of the next files data;
pbTemp += fileBuf.uiFileSize;
uiCurrentByte += DLC_DETAIL_ADV(fileBuf.dwWchCount);
ReadDlcStruct(&fileBuf, pbData, uiCurrentByte);
}
parameterMapping.clear();
return packId;
}
+110
View File
@@ -0,0 +1,110 @@
#pragma once
// using namespace std;
#include <cstdint>
#include <string>
#include <vector>
class DLCPack;
class DLCSkinFile;
class DLCManager {
public:
enum EDLCType {
e_DLCType_Skin = 0,
e_DLCType_Cape,
e_DLCType_Texture,
e_DLCType_UIData,
e_DLCType_PackConfig,
e_DLCType_TexturePack,
e_DLCType_LocalisationData,
e_DLCType_GameRules,
e_DLCType_Audio,
e_DLCType_ColourTable,
e_DLCType_GameRulesHeader,
e_DLCType_Max,
e_DLCType_All,
};
// If you add to the Enum,then you need to add the array of type names
// These are the names used in the XML for the parameters
enum EDLCParameterType {
e_DLCParamType_Invalid = -1,
e_DLCParamType_DisplayName = 0,
e_DLCParamType_ThemeName,
e_DLCParamType_Free, // identify free skins
e_DLCParamType_Credit, // legal credits for DLC
e_DLCParamType_Cape,
e_DLCParamType_Box,
e_DLCParamType_Anim,
e_DLCParamType_PackId,
e_DLCParamType_NetherParticleColour,
e_DLCParamType_EnchantmentTextColour,
e_DLCParamType_EnchantmentTextFocusColour,
e_DLCParamType_DataPath,
e_DLCParamType_PackVersion,
e_DLCParamType_Max,
};
const static wchar_t* wchTypeNamesA[e_DLCParamType_Max];
private:
std::vector<DLCPack*> m_packs;
// bool m_bNeedsUpdated;
bool m_bNeedsCorruptCheck;
unsigned int m_dwUnnamedCorruptDLCCount;
public:
DLCManager();
~DLCManager();
static EDLCParameterType getParameterType(const std::wstring& paramName);
unsigned int getPackCount(EDLCType type = e_DLCType_All);
// bool NeedsUpdated() { return m_bNeedsUpdated; }
// void SetNeedsUpdated(bool val) { m_bNeedsUpdated = val; }
bool NeedsCorruptCheck() { return m_bNeedsCorruptCheck; }
void SetNeedsCorruptCheck(bool val) { m_bNeedsCorruptCheck = val; }
void resetUnnamedCorruptCount() { m_dwUnnamedCorruptDLCCount = 0; }
void incrementUnnamedCorruptCount() { ++m_dwUnnamedCorruptDLCCount; }
void addPack(DLCPack* pack);
void removePack(DLCPack* pack);
void removeAllPacks(void);
void LanguageChanged(void);
DLCPack* getPack(const std::wstring& name);
DLCPack* getPack(unsigned int index, EDLCType type = e_DLCType_All);
unsigned int getPackIndex(DLCPack* pack, bool& found,
EDLCType type = e_DLCType_All);
DLCSkinFile* getSkinFile(
const std::wstring& path); // Will hunt all packs of type skin to find
// the right skinfile
DLCPack* getPackContainingSkin(const std::wstring& path);
unsigned int getPackIndexContainingSkin(const std::wstring& path,
bool& found);
unsigned int checkForCorruptDLCAndAlert(bool showMessage = true);
bool readDLCDataFile(unsigned int& dwFilesProcessed,
const std::wstring& path, DLCPack* pack,
bool fromArchive = false);
bool readDLCDataFile(unsigned int& dwFilesProcessed,
const std::string& path, DLCPack* pack,
bool fromArchive = false);
std::uint32_t retrievePackIDFromDLCDataFile(const std::string& path,
DLCPack* pack);
private:
bool processDLCDataFile(unsigned int& dwFilesProcessed,
std::uint8_t* pbData, unsigned int dwLength,
DLCPack* pack);
std::uint32_t retrievePackID(std::uint8_t* pbData, unsigned int dwLength,
DLCPack* pack);
};
+357
View File
@@ -0,0 +1,357 @@
#include "DLCPack.h"
#include <wchar.h>
#include <algorithm>
#include <sstream>
#include <utility>
#include "platform/sdl2/Profile.h"
#include "DLCAudioFile.h"
#include "DLCCapeFile.h"
#include "DLCColourTableFile.h"
#include "DLCGameRulesFile.h"
#include "DLCGameRulesHeader.h"
#include "DLCLocalisationFile.h"
#include "DLCTextureFile.h"
#include "DLCUIDataFile.h"
#include "app/common/src/Console_Debug_enum.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/common/src/DLC/DLCManager.h"
#include "app/common/src/DLC/DLCSkinFile.h"
#include "app/common/src/Localisation/StringTable.h"
#include "app/linux/Linux_App.h"
#include "app/linux/Stubs/winapi_stubs.h"
#include "console_helpers/StringHelpers.h"
DLCPack::DLCPack(const std::wstring& name, std::uint32_t dwLicenseMask) {
m_dataPath = L"";
m_packName = name;
m_dwLicenseMask = dwLicenseMask;
m_ullFullOfferId = 0LL;
m_isCorrupt = false;
m_packId = 0;
m_packVersion = 0;
m_parentPack = nullptr;
m_dlcMountIndex = -1;
// This pointer is for all the data used for this pack, so deleting it
// invalidates ALL of it's children.
m_data = nullptr;
}
DLCPack::~DLCPack() {
for (auto it = m_childPacks.begin(); it != m_childPacks.end(); ++it) {
delete *it;
}
for (unsigned int i = 0; i < DLCManager::e_DLCType_Max; ++i) {
for (auto it = m_files[i].begin(); it != m_files[i].end(); ++it) {
delete *it;
}
}
// This pointer is for all the data used for this pack, so deleting it
// invalidates ALL of it's children.
if (m_data) {
#if !defined(_CONTENT_PACKAGE)
wprintf(L"Deleting data for DLC pack %ls\n", m_packName.c_str());
#endif
// For the same reason, don't delete data pointer for any child pack as
// it just points to a region within the parent pack that has already
// been freed
if (m_parentPack == nullptr) {
delete[] m_data;
}
}
}
int DLCPack::GetDLCMountIndex() {
if (m_parentPack != nullptr) {
return m_parentPack->GetDLCMountIndex();
}
return m_dlcMountIndex;
}
XCONTENTDEVICEID DLCPack::GetDLCDeviceID() {
if (m_parentPack != nullptr) {
return m_parentPack->GetDLCDeviceID();
}
return m_dlcDeviceID;
}
void DLCPack::addChildPack(DLCPack* childPack) {
const std::uint32_t packId = childPack->GetPackId();
#if !defined(_CONTENT_PACKAGE)
if (packId < 0 || packId > 15) {
__debugbreak();
}
#endif
childPack->SetPackId((packId << 24) | m_packId);
m_childPacks.push_back(childPack);
childPack->setParentPack(this);
childPack->m_packName = m_packName + childPack->getName();
}
void DLCPack::setParentPack(DLCPack* parentPack) { m_parentPack = parentPack; }
void DLCPack::addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value) {
switch (type) {
case DLCManager::e_DLCParamType_PackId: {
std::uint32_t packId = 0;
std::wstringstream ss;
// 4J Stu - numbered using decimal to make it easier for
// artists/people to number manually
ss << std::dec << value.c_str();
ss >> packId;
SetPackId(packId);
} break;
case DLCManager::e_DLCParamType_PackVersion: {
std::uint32_t version = 0;
std::wstringstream ss;
// 4J Stu - numbered using decimal to make it easier for
// artists/people to number manually
ss << std::dec << value.c_str();
ss >> version;
SetPackVersion(version);
} break;
case DLCManager::e_DLCParamType_DisplayName:
m_packName = value;
break;
case DLCManager::e_DLCParamType_DataPath:
m_dataPath = value;
break;
default:
m_parameters[(int)type] = value;
break;
}
}
bool DLCPack::getParameterAsUInt(DLCManager::EDLCParameterType type,
unsigned int& param) {
auto it = m_parameters.find((int)type);
if (it != m_parameters.end()) {
switch (type) {
case DLCManager::e_DLCParamType_NetherParticleColour:
case DLCManager::e_DLCParamType_EnchantmentTextColour:
case DLCManager::e_DLCParamType_EnchantmentTextFocusColour: {
std::wstringstream ss;
ss << std::hex << it->second.c_str();
ss >> param;
} break;
default:
param = _fromString<unsigned int>(it->second);
}
return true;
}
return false;
}
DLCFile* DLCPack::addFile(DLCManager::EDLCType type, const std::wstring& path) {
DLCFile* newFile = nullptr;
switch (type) {
case DLCManager::e_DLCType_Skin: {
std::vector<std::wstring> splitPath = stringSplit(path, L'/');
std::wstring strippedPath = splitPath.back();
newFile = new DLCSkinFile(strippedPath);
// check to see if we can get the full offer id using this skin name
uint64_t ullVal = 0LL;
if (app.GetDLCFullOfferIDForSkinID(strippedPath, &ullVal)) {
m_ullFullOfferId = ullVal;
}
} break;
case DLCManager::e_DLCType_Cape: {
std::vector<std::wstring> splitPath = stringSplit(path, L'/');
std::wstring strippedPath = splitPath.back();
newFile = new DLCCapeFile(strippedPath);
} break;
case DLCManager::e_DLCType_Texture:
newFile = new DLCTextureFile(path);
break;
case DLCManager::e_DLCType_UIData:
newFile = new DLCUIDataFile(path);
break;
case DLCManager::e_DLCType_LocalisationData:
newFile = new DLCLocalisationFile(path);
break;
case DLCManager::e_DLCType_GameRules:
newFile = new DLCGameRulesFile(path);
break;
case DLCManager::e_DLCType_Audio:
newFile = new DLCAudioFile(path);
break;
case DLCManager::e_DLCType_ColourTable:
newFile = new DLCColourTableFile(path);
break;
case DLCManager::e_DLCType_GameRulesHeader:
newFile = new DLCGameRulesHeader(path);
break;
default:
break;
};
if (newFile != nullptr) {
m_files[newFile->getType()].push_back(newFile);
}
return newFile;
}
// MGH - added this comp func, as the embedded func in find_if was confusing the
// PS3 compiler
static const std::wstring* g_pathCmpString = nullptr;
static bool pathCmp(DLCFile* val) {
return (g_pathCmpString->compare(val->getPath()) == 0);
}
bool DLCPack::doesPackContainFile(DLCManager::EDLCType type,
const std::wstring& path) {
bool hasFile = false;
if (type == DLCManager::e_DLCType_All) {
for (DLCManager::EDLCType currentType = (DLCManager::EDLCType)0;
currentType < DLCManager::e_DLCType_Max;
currentType = (DLCManager::EDLCType)(currentType + 1)) {
hasFile = doesPackContainFile(currentType, path);
if (hasFile) break;
}
} else {
g_pathCmpString = &path;
auto it =
std::find_if(m_files[type].begin(), m_files[type].end(), pathCmp);
hasFile = it != m_files[type].end();
if (!hasFile && m_parentPack) {
hasFile = m_parentPack->doesPackContainFile(type, path);
}
}
return hasFile;
}
DLCFile* DLCPack::getFile(DLCManager::EDLCType type, unsigned int index) {
DLCFile* file = nullptr;
if (type == DLCManager::e_DLCType_All) {
for (DLCManager::EDLCType currentType = (DLCManager::EDLCType)0;
currentType < DLCManager::e_DLCType_Max;
currentType = (DLCManager::EDLCType)(currentType + 1)) {
file = getFile(currentType, index);
if (file != nullptr) break;
}
} else {
if (m_files[type].size() > index) file = m_files[type][index];
if (!file && m_parentPack) {
file = m_parentPack->getFile(type, index);
}
}
return file;
}
DLCFile* DLCPack::getFile(DLCManager::EDLCType type, const std::wstring& path) {
DLCFile* file = nullptr;
if (type == DLCManager::e_DLCType_All) {
for (DLCManager::EDLCType currentType = (DLCManager::EDLCType)0;
currentType < DLCManager::e_DLCType_Max;
currentType = (DLCManager::EDLCType)(currentType + 1)) {
file = getFile(currentType, path);
if (file != nullptr) break;
}
} else {
g_pathCmpString = &path;
auto it =
std::find_if(m_files[type].begin(), m_files[type].end(), pathCmp);
if (it == m_files[type].end()) {
// Not found
file = nullptr;
} else {
file = *it;
}
if (!file && m_parentPack) {
file = m_parentPack->getFile(type, path);
}
}
return file;
}
unsigned int DLCPack::getDLCItemsCount(
DLCManager::EDLCType type /*= DLCManager::e_DLCType_All*/) {
unsigned int count = 0;
switch (type) {
case DLCManager::e_DLCType_All:
for (int i = 0; i < DLCManager::e_DLCType_Max; ++i) {
count += getDLCItemsCount((DLCManager::EDLCType)i);
}
break;
default:
count = static_cast<unsigned int>(m_files[(int)type].size());
break;
};
return count;
};
unsigned int DLCPack::getFileIndexAt(DLCManager::EDLCType type,
const std::wstring& path, bool& found) {
if (type == DLCManager::e_DLCType_All) {
app.DebugPrintf("Unimplemented\n");
#if !defined(__CONTENT_PACKAGE)
__debugbreak();
#endif
return 0;
}
unsigned int foundIndex = 0;
found = false;
unsigned int index = 0;
for (auto it = m_files[type].begin(); it != m_files[type].end(); ++it) {
if (path.compare((*it)->getPath()) == 0) {
foundIndex = index;
found = true;
break;
}
++index;
}
return foundIndex;
}
bool DLCPack::hasPurchasedFile(DLCManager::EDLCType type,
const std::wstring& path) {
if (type == DLCManager::e_DLCType_All) {
app.DebugPrintf("Unimplemented\n");
#if !defined(_CONTENT_PACKAGE)
__debugbreak();
#endif
return false;
}
#if !defined(_CONTENT_PACKAGE)
if (app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_UnlockAllDLC)) {
return true;
} else
#endif
if (m_dwLicenseMask == 0) {
// not purchased.
return false;
} else {
// purchased
return true;
}
}
void DLCPack::UpdateLanguage() {
// find the language file
if (m_files[DLCManager::e_DLCType_LocalisationData].size() > 0) {
DLCLocalisationFile* localisationFile = (DLCLocalisationFile*)getFile(
DLCManager::e_DLCType_LocalisationData, L"languages.loc");
StringTable* strTable = localisationFile->getStringTable();
strTable->ReloadStringTable();
}
}
+108
View File
@@ -0,0 +1,108 @@
#pragma once
// using namespace std;
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
#include "4J.Common/4J_Compat.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCSkinFile.h"
class DLCFile;
class DLCSkinFile;
class DLCPack {
private:
std::vector<DLCFile*> m_files[DLCManager::e_DLCType_Max];
std::vector<DLCPack*> m_childPacks;
DLCPack* m_parentPack;
std::unordered_map<int, std::wstring> m_parameters;
std::wstring m_packName;
std::wstring m_dataPath;
std::uint32_t m_dwLicenseMask;
int m_dlcMountIndex;
XCONTENTDEVICEID m_dlcDeviceID;
uint64_t m_ullFullOfferId;
bool m_isCorrupt;
std::uint32_t m_packId;
std::uint32_t m_packVersion;
std::uint8_t*
m_data; // This pointer is for all the data used for this pack, so
// deleting it invalidates ALL of it's children.
public:
DLCPack(const std::wstring& name, std::uint32_t dwLicenseMask);
~DLCPack();
std::wstring getFullDataPath() { return m_dataPath; }
void SetDataPointer(std::uint8_t* pbData) { m_data = pbData; }
bool IsCorrupt() { return m_isCorrupt; }
void SetIsCorrupt(bool val) { m_isCorrupt = val; }
void SetPackId(std::uint32_t id) { m_packId = id; }
std::uint32_t GetPackId() { return m_packId; }
void SetPackVersion(std::uint32_t version) { m_packVersion = version; }
std::uint32_t GetPackVersion() { return m_packVersion; }
DLCPack* GetParentPack() { return m_parentPack; }
std::uint32_t GetParentPackId() { return m_parentPack->m_packId; }
void SetDLCMountIndex(int id) { m_dlcMountIndex = id; }
int GetDLCMountIndex();
void SetDLCDeviceID(XCONTENTDEVICEID deviceId) { m_dlcDeviceID = deviceId; }
XCONTENTDEVICEID GetDLCDeviceID();
void addChildPack(DLCPack* childPack);
void setParentPack(DLCPack* parentPack);
void addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value);
bool getParameterAsUInt(DLCManager::EDLCParameterType type,
unsigned int& param);
void updateLicenseMask(std::uint32_t dwLicenseMask) {
m_dwLicenseMask = dwLicenseMask;
}
std::uint32_t getLicenseMask() { return m_dwLicenseMask; }
std::wstring getName() { return m_packName; }
void UpdateLanguage();
uint64_t getPurchaseOfferId() { return m_ullFullOfferId; }
DLCFile* addFile(DLCManager::EDLCType type, const std::wstring& path);
DLCFile* getFile(DLCManager::EDLCType type, unsigned int index);
DLCFile* getFile(DLCManager::EDLCType type, const std::wstring& path);
unsigned int getDLCItemsCount(
DLCManager::EDLCType type = DLCManager::e_DLCType_All);
unsigned int getFileIndexAt(DLCManager::EDLCType type,
const std::wstring& path, bool& found);
bool doesPackContainFile(DLCManager::EDLCType type,
const std::wstring& path);
std::uint32_t GetPackID() { return m_packId; }
unsigned int getSkinCount() {
return getDLCItemsCount(DLCManager::e_DLCType_Skin);
}
unsigned int getSkinIndexAt(const std::wstring& path, bool& found) {
return getFileIndexAt(DLCManager::e_DLCType_Skin, path, found);
}
DLCSkinFile* getSkinFile(const std::wstring& path) {
return (DLCSkinFile*)getFile(DLCManager::e_DLCType_Skin, path);
}
DLCSkinFile* getSkinFile(unsigned int index) {
return (DLCSkinFile*)getFile(DLCManager::e_DLCType_Skin, index);
}
bool doesPackContainSkin(const std::wstring& path) {
return doesPackContainFile(DLCManager::e_DLCType_Skin, path);
}
bool hasPurchasedFile(DLCManager::EDLCType type, const std::wstring& path);
};
+179
View File
@@ -0,0 +1,179 @@
#include "DLCSkinFile.h"
#include <string.h>
#include <wchar.h>
#include "platform/sdl2/Render.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/linux/Linux_App.h"
#include "app/include/SkinBox.h"
#include "app/include/XboxStubs.h"
DLCSkinFile::DLCSkinFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_Skin, path) {
m_displayName = L"";
m_themeName = L"";
m_cape = L"";
m_bIsFree = false;
m_uiAnimOverrideBitmask = 0L;
}
void DLCSkinFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes) {
app.AddMemoryTextureFile(m_path, pbData, dataBytes);
}
void DLCSkinFile::addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value) {
switch (type) {
case DLCManager::e_DLCParamType_DisplayName: {
// 4J Stu - In skin pack 2, the name for Zap is mis-spelt with two
// p's as Zapp dlcskin00000109.png
if (m_path.compare(L"dlcskin00000109.png") == 0) {
m_displayName = L"Zap";
} else {
m_displayName = value;
}
} break;
case DLCManager::e_DLCParamType_ThemeName:
m_themeName = value;
break;
case DLCManager::e_DLCParamType_Free: // If this parameter exists, then
// mark this as free
m_bIsFree = true;
break;
case DLCManager::e_DLCParamType_Credit: // If this parameter exists,
// then mark this as free
// add it to the DLC credits
// list
// we'll need to justify this text since we don't have a lot of room
// for lines of credits
{
if (app.AlreadySeenCreditText(value)) break;
// first add a blank string for spacing
app.AddCreditText(L"");
int maximumChars = 55;
bool bIsSDMode =
!RenderManager.IsHiDef() && !RenderManager.IsWidescreen();
if (bIsSDMode) {
maximumChars = 45;
}
switch (XGetLanguage()) {
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
maximumChars = 35;
break;
default:
break;
}
std::wstring creditValue = value;
while (creditValue.length() > maximumChars) {
unsigned int i = 1;
while (i < creditValue.length() &&
(i + 1) <= maximumChars) {
i++;
}
int iLast = (int)creditValue.find_last_of(L" ", i);
switch (XGetLanguage()) {
case XC_LANGUAGE_JAPANESE:
case XC_LANGUAGE_TCHINESE:
case XC_LANGUAGE_KOREAN:
iLast = maximumChars;
break;
default:
iLast = (int)creditValue.find_last_of(L" ", i);
break;
}
// if a space was found, include the space on this line
if (iLast != i) {
iLast++;
}
app.AddCreditText((creditValue.substr(0, iLast)).c_str());
creditValue = creditValue.substr(iLast);
}
app.AddCreditText(creditValue.c_str());
}
break;
case DLCManager::e_DLCParamType_Cape:
m_cape = value;
break;
case DLCManager::e_DLCParamType_Box: {
wchar_t wchBodyPart[10];
SKIN_BOX* pSkinBox = new SKIN_BOX;
memset(pSkinBox, 0, sizeof(SKIN_BOX));
swscanf(value.c_str(), L"%9ls%f%f%f%f%f%f%f%f", wchBodyPart, 10,
&pSkinBox->fX, &pSkinBox->fY, &pSkinBox->fZ, &pSkinBox->fW,
&pSkinBox->fH, &pSkinBox->fD, &pSkinBox->fU, &pSkinBox->fV);
if (wcscmp(wchBodyPart, L"HEAD") == 0) {
pSkinBox->ePart = eBodyPart_Head;
} else if (wcscmp(wchBodyPart, L"BODY") == 0) {
pSkinBox->ePart = eBodyPart_Body;
} else if (wcscmp(wchBodyPart, L"ARM0") == 0) {
pSkinBox->ePart = eBodyPart_Arm0;
} else if (wcscmp(wchBodyPart, L"ARM1") == 0) {
pSkinBox->ePart = eBodyPart_Arm1;
} else if (wcscmp(wchBodyPart, L"LEG0") == 0) {
pSkinBox->ePart = eBodyPart_Leg0;
} else if (wcscmp(wchBodyPart, L"LEG1") == 0) {
pSkinBox->ePart = eBodyPart_Leg1;
}
// add this to the skin's vector of parts
m_AdditionalBoxes.push_back(pSkinBox);
} break;
case DLCManager::e_DLCParamType_Anim: {
swscanf(value.c_str(), L"%X", &m_uiAnimOverrideBitmask,
sizeof(unsigned int));
uint32_t skinId = app.getSkinIdFromPath(m_path);
app.SetAnimOverrideBitmask(skinId, m_uiAnimOverrideBitmask);
break;
}
default:
break;
}
}
// std::vector<ModelPart *> *DLCSkinFile::getAdditionalModelParts()
// {
// return &m_AdditionalModelParts;
// }
int DLCSkinFile::getAdditionalBoxesCount() {
return (int)m_AdditionalBoxes.size();
}
std::vector<SKIN_BOX*>* DLCSkinFile::getAdditionalBoxes() {
return &m_AdditionalBoxes;
}
std::wstring DLCSkinFile::getParameterAsString(
DLCManager::EDLCParameterType type) {
switch (type) {
case DLCManager::e_DLCParamType_DisplayName:
return m_displayName;
case DLCManager::e_DLCParamType_ThemeName:
return m_themeName;
case DLCManager::e_DLCParamType_Cape:
return m_cape;
default:
return L"";
}
}
bool DLCSkinFile::getParameterAsBool(DLCManager::EDLCParameterType type) {
switch (type) {
case DLCManager::e_DLCParamType_Free:
return m_bIsFree;
default:
return false;
}
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include <cstdint>
#include <format>
#include <string>
#include <vector>
#include "DLCFile.h"
#include "app/common/src/DLC/DLCManager.h"
#include "app/include/SkinBox.h"
#include "minecraft/client/model/HumanoidModel.h"
class DLCSkinFile : public DLCFile {
private:
std::wstring m_displayName;
std::wstring m_themeName;
std::wstring m_cape;
unsigned int m_uiAnimOverrideBitmask;
bool m_bIsFree;
std::vector<SKIN_BOX*> m_AdditionalBoxes;
public:
DLCSkinFile(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
virtual void addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value);
virtual std::wstring getParameterAsString(
DLCManager::EDLCParameterType type);
virtual bool getParameterAsBool(DLCManager::EDLCParameterType type);
std::vector<SKIN_BOX*>* getAdditionalBoxes();
int getAdditionalBoxesCount();
unsigned int getAnimOverrideBitmask() { return m_uiAnimOverrideBitmask; }
bool isFree() { return m_bIsFree; }
};
@@ -0,0 +1,56 @@
#include "DLCTextureFile.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
DLCTextureFile::DLCTextureFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_Texture, path) {
m_bIsAnim = false;
m_animString = L"";
m_pbData = nullptr;
m_dataBytes = 0;
}
void DLCTextureFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes) {
// app.AddMemoryTextureFile(m_path,pbData,dwBytes);
m_pbData = pbData;
m_dataBytes = dataBytes;
}
std::uint8_t* DLCTextureFile::getData(std::uint32_t& dataBytes) {
dataBytes = m_dataBytes;
return m_pbData;
}
void DLCTextureFile::addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value) {
switch (type) {
case DLCManager::e_DLCParamType_Anim:
m_animString = value;
m_bIsAnim = true;
break;
default:
break;
}
}
std::wstring DLCTextureFile::getParameterAsString(
DLCManager::EDLCParameterType type) {
switch (type) {
case DLCManager::e_DLCParamType_Anim:
return m_animString;
default:
return L"";
}
}
bool DLCTextureFile::getParameterAsBool(DLCManager::EDLCParameterType type) {
switch (type) {
case DLCManager::e_DLCParamType_Anim:
return m_bIsAnim;
default:
return false;
}
}
@@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCFile.h"
#include "app/common/src/DLC/DLCManager.h"
class DLCTextureFile : public DLCFile {
private:
bool m_bIsAnim;
std::wstring m_animString;
std::uint8_t* m_pbData;
std::uint32_t m_dataBytes;
public:
DLCTextureFile(const std::wstring& path);
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes);
virtual std::uint8_t* getData(std::uint32_t& dataBytes);
virtual void addParameter(DLCManager::EDLCParameterType type,
const std::wstring& value);
virtual std::wstring getParameterAsString(
DLCManager::EDLCParameterType type);
virtual bool getParameterAsBool(DLCManager::EDLCParameterType type);
};
@@ -0,0 +1,31 @@
#include "DLCUIDataFile.h"
#include "DLCManager.h"
#include "app/common/src/DLC/DLCFile.h"
#include "app/linux/Linux_App.h"
DLCUIDataFile::DLCUIDataFile(const std::wstring& path)
: DLCFile(DLCManager::e_DLCType_UIData, path) {
m_pbData = nullptr;
m_dataBytes = 0;
m_canDeleteData = false;
}
DLCUIDataFile::~DLCUIDataFile() {
if (m_canDeleteData && m_pbData != nullptr) {
app.DebugPrintf("Deleting DLCUIDataFile data\n");
delete[] m_pbData;
}
}
void DLCUIDataFile::addData(std::uint8_t* pbData, std::uint32_t dataBytes,
bool canDeleteData) {
m_pbData = pbData;
m_dataBytes = dataBytes;
m_canDeleteData = canDeleteData;
}
std::uint8_t* DLCUIDataFile::getData(std::uint32_t& dataBytes) {
dataBytes = m_dataBytes;
return m_pbData;
}
@@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <string>
#include "DLCFile.h"
class DLCUIDataFile : public DLCFile {
private:
std::uint8_t* m_pbData;
std::uint32_t m_dataBytes;
bool m_canDeleteData;
public:
DLCUIDataFile(const std::wstring& path);
~DLCUIDataFile();
using DLCFile::addData;
using DLCFile::addParameter;
virtual void addData(std::uint8_t* pbData, std::uint32_t dataBytes,
bool canDeleteData = false);
virtual std::uint8_t* getData(std::uint32_t& dataBytes);
};
@@ -0,0 +1,25 @@
#pragma once
#include "ConsoleGameRulesConstants.h"
#include "GameRuleManager.h"
#include "app/common/src/GameRules/LevelGeneration/ApplySchematicRuleDefinition.h"
#include "app/common/src/GameRules/LevelGeneration/BiomeOverride.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructure.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerationOptions.h"
#include "app/common/src/GameRules/LevelGeneration/StartFeature.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionGenerateBox.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceBlock.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceContainer.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceSpawner.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/AddEnchantmentRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/AddItemRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CollectItemRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompleteAllRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompoundGameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/LevelRuleset.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/NamedAreaRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/UpdatePlayerRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/UseTileRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
@@ -0,0 +1,118 @@
#pragma once
#include "java/InputOutputStream/DataOutputStream.h"
class ConsoleGameRules {
public:
enum EGameRuleType {
eGameRuleType_Invalid = -1,
eGameRuleType_Root =
0, // This is the top level rule that defines a game mode, this is
// used to generate data for new players
eGameRuleType_LevelGenerationOptions,
eGameRuleType_ApplySchematic,
eGameRuleType_GenerateStructure,
eGameRuleType_GenerateBox,
eGameRuleType_PlaceBlock,
eGameRuleType_PlaceContainer,
eGameRuleType_PlaceSpawner,
eGameRuleType_BiomeOverride,
eGameRuleType_StartFeature,
eGameRuleType_AddItem,
eGameRuleType_AddEnchantment,
eGameRuleType_LevelRules,
eGameRuleType_NamedArea,
eGameRuleType_UseTileRule,
eGameRuleType_CollectItemRule,
eGameRuleType_CompleteAllRule,
eGameRuleType_UpdatePlayerRule,
eGameRuleType_Count
};
enum EGameRuleAttr {
eGameRuleAttr_Invalid = -1,
eGameRuleAttr_descriptionName = 0,
eGameRuleAttr_promptName,
eGameRuleAttr_dataTag,
eGameRuleAttr_enchantmentId,
eGameRuleAttr_enchantmentLevel,
eGameRuleAttr_itemId,
eGameRuleAttr_quantity,
eGameRuleAttr_auxValue,
eGameRuleAttr_slot,
eGameRuleAttr_name,
eGameRuleAttr_food,
eGameRuleAttr_health,
eGameRuleAttr_tileId,
eGameRuleAttr_useCoords,
eGameRuleAttr_seed,
eGameRuleAttr_flatworld,
eGameRuleAttr_filename,
eGameRuleAttr_rot,
eGameRuleAttr_data,
eGameRuleAttr_block,
eGameRuleAttr_entity,
eGameRuleAttr_facing,
eGameRuleAttr_edgeTile,
eGameRuleAttr_fillTile,
eGameRuleAttr_skipAir,
eGameRuleAttr_x,
eGameRuleAttr_x0,
eGameRuleAttr_x1,
eGameRuleAttr_y,
eGameRuleAttr_y0,
eGameRuleAttr_y1,
eGameRuleAttr_z,
eGameRuleAttr_z0,
eGameRuleAttr_z1,
eGameRuleAttr_chunkX,
eGameRuleAttr_chunkZ,
eGameRuleAttr_yRot,
eGameRuleAttr_spawnX,
eGameRuleAttr_spawnY,
eGameRuleAttr_spawnZ,
eGameRuleAttr_orientation,
eGameRuleAttr_dimension,
eGameRuleAttr_topTileId,
eGameRuleAttr_biomeId,
eGameRuleAttr_feature,
eGameRuleAttr_Count
};
static void write(DataOutputStream* dos,
ConsoleGameRules::EGameRuleType eType) {
dos->writeInt(eType);
}
static void write(DataOutputStream* dos,
ConsoleGameRules::EGameRuleAttr eAttr) {
dos->writeInt(static_cast<int>(eGameRuleType_Count) +
static_cast<int>(eAttr));
}
};
@@ -0,0 +1,748 @@
#include "GameRuleManager.h"
#include <assert.h>
#include <string.h>
#include <cstdint>
#include <utility>
#include <vector>
#include "app/common/src/DLC/DLCGameRulesFile.h"
#include "app/common/src/DLC/DLCGameRulesHeader.h"
#include "app/common/src/DLC/DLCLocalisationFile.h"
#include "app/common/src/DLC/DLCManager.h"
#include "app/common/src/DLC/DLCPack.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleSchematicFile.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerationOptions.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerators.h"
#include "app/common/src/GameRules/LevelRules/LevelRules.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/LevelRuleset.h"
#include "app/common/src/Localisation/StringTable.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/compression.h"
#include "java/File.h"
#include "java/InputOutputStream/ByteArrayInputStream.h"
#include "java/InputOutputStream/ByteArrayOutputStream.h"
#include "java/InputOutputStream/DataInputStream.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/level/storage/ConsoleSaveFileIO/FileHeader.h"
#include "strings.h"
const wchar_t* GameRuleManager::wchTagNameA[] = {
L"", // eGameRuleType_Root
L"MapOptions", // eGameRuleType_LevelGenerationOptions
L"ApplySchematic", // eGameRuleType_ApplySchematic
L"GenerateStructure", // eGameRuleType_GenerateStructure
L"GenerateBox", // eGameRuleType_GenerateBox
L"PlaceBlock", // eGameRuleType_PlaceBlock
L"PlaceContainer", // eGameRuleType_PlaceContainer
L"PlaceSpawner", // eGameRuleType_PlaceSpawner
L"BiomeOverride", // eGameRuleType_BiomeOverride
L"StartFeature", // eGameRuleType_StartFeature
L"AddItem", // eGameRuleType_AddItem
L"AddEnchantment", // eGameRuleType_AddEnchantment
L"LevelRules", // eGameRuleType_LevelRules
L"NamedArea", // eGameRuleType_NamedArea
L"UseTile", // eGameRuleType_UseTileRule
L"CollectItem", // eGameRuleType_CollectItemRule
L"CompleteAll", // eGameRuleType_CompleteAllRule
L"UpdatePlayer", // eGameRuleType_UpdatePlayerRule
};
const wchar_t* GameRuleManager::wchAttrNameA[] = {
L"descriptionName", // eGameRuleAttr_descriptionName
L"promptName", // eGameRuleAttr_promptName
L"dataTag", // eGameRuleAttr_dataTag
L"enchantmentId", // eGameRuleAttr_enchantmentId
L"enchantmentLevel", // eGameRuleAttr_enchantmentLevel
L"itemId", // eGameRuleAttr_itemId
L"quantity", // eGameRuleAttr_quantity
L"auxValue", // eGameRuleAttr_auxValue
L"slot", // eGameRuleAttr_slot
L"name", // eGameRuleAttr_name
L"food", // eGameRuleAttr_food
L"health", // eGameRuleAttr_health
L"tileId", // eGameRuleAttr_tileId
L"useCoords", // eGameRuleAttr_useCoords
L"seed", // eGameRuleAttr_seed
L"flatworld", // eGameRuleAttr_flatworld
L"filename", // eGameRuleAttr_filename
L"rot", // eGameRuleAttr_rot
L"data", // eGameRuleAttr_data
L"block", // eGameRuleAttr_block
L"entity", // eGameRuleAttr_entity
L"facing", // eGameRuleAttr_facing
L"edgeTile", // eGameRuleAttr_edgeTile
L"fillTile", // eGameRuleAttr_fillTile
L"skipAir", // eGameRuleAttr_skipAir
L"x", // eGameRuleAttr_x
L"x0", // eGameRuleAttr_x0
L"x1", // eGameRuleAttr_x1
L"y", // eGameRuleAttr_y
L"y0", // eGameRuleAttr_y0
L"y1", // eGameRuleAttr_y1
L"z", // eGameRuleAttr_z
L"z0", // eGameRuleAttr_z0
L"z1", // eGameRuleAttr_z1
L"chunkX", // eGameRuleAttr_chunkX
L"chunkZ", // eGameRuleAttr_chunkZ
L"yRot", // eGameRuleAttr_yRot
L"spawnX", // eGameRuleAttr_spawnX
L"spawnY", // eGameRuleAttr_spawnY
L"spawnZ", // eGameRuleAttr_spawnZ
L"orientation",
L"dimension",
L"topTileId", // eGameRuleAttr_topTileId
L"biomeId", // eGameRuleAttr_biomeId
L"feature", // eGameRuleAttr_feature
};
GameRuleManager::GameRuleManager() {
m_currentGameRuleDefinitions = nullptr;
m_currentLevelGenerationOptions = nullptr;
}
void GameRuleManager::loadGameRules(DLCPack* pack) {
StringTable* strings = nullptr;
if (pack->doesPackContainFile(DLCManager::e_DLCType_LocalisationData,
L"languages.loc")) {
DLCLocalisationFile* localisationFile =
(DLCLocalisationFile*)pack->getFile(
DLCManager::e_DLCType_LocalisationData, L"languages.loc");
strings = localisationFile->getStringTable();
}
int gameRulesCount =
pack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader);
for (int i = 0; i < gameRulesCount; ++i) {
DLCGameRulesHeader* dlcHeader = (DLCGameRulesHeader*)pack->getFile(
DLCManager::e_DLCType_GameRulesHeader, i);
std::uint32_t dSize;
uint8_t* dData = dlcHeader->getData(dSize);
LevelGenerationOptions* createdLevelGenerationOptions =
new LevelGenerationOptions(pack);
// = loadGameRules(dData, dSize); //, strings);
createdLevelGenerationOptions->setGrSource(dlcHeader);
createdLevelGenerationOptions->setSrc(
LevelGenerationOptions::eSrc_fromDLC);
readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
dlcHeader->lgo = createdLevelGenerationOptions;
}
gameRulesCount = pack->getDLCItemsCount(DLCManager::e_DLCType_GameRules);
for (int i = 0; i < gameRulesCount; ++i) {
DLCGameRulesFile* dlcFile = (DLCGameRulesFile*)pack->getFile(
DLCManager::e_DLCType_GameRules, i);
std::uint32_t dSize;
uint8_t* dData = dlcFile->getData(dSize);
LevelGenerationOptions* createdLevelGenerationOptions =
new LevelGenerationOptions(pack);
// = loadGameRules(dData, dSize); //, strings);
createdLevelGenerationOptions->setGrSource(new JustGrSource());
createdLevelGenerationOptions->setSrc(
LevelGenerationOptions::eSrc_tutorial);
readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
createdLevelGenerationOptions->setLoadedData();
}
}
LevelGenerationOptions* GameRuleManager::loadGameRules(uint8_t* dIn,
unsigned int dSize) {
LevelGenerationOptions* lgo = new LevelGenerationOptions();
lgo->setGrSource(new JustGrSource());
lgo->setSrc(LevelGenerationOptions::eSrc_fromSave);
loadGameRules(lgo, dIn, dSize);
lgo->setLoadedData();
return lgo;
}
// 4J-JEV: Reverse of saveGameRules.
void GameRuleManager::loadGameRules(LevelGenerationOptions* lgo, uint8_t* dIn,
unsigned int dSize) {
app.DebugPrintf("GameRuleManager::LoadingGameRules:\n");
std::vector<uint8_t> inputBuf(dIn, dIn + dSize);
ByteArrayInputStream bais(inputBuf);
DataInputStream dis(&bais);
// Read file header.
// dis.readInt(); // File Size
short version = dis.readShort();
assert(0x1 == version);
app.DebugPrintf("\tversion=%d.\n", version);
for (int i = 0; i < 8; i++) dis.readByte();
std::uint8_t compression_type = dis.readByte();
app.DebugPrintf("\tcompressionType=%d.\n", compression_type);
unsigned int compr_len, decomp_len;
compr_len = dis.readInt();
decomp_len = dis.readInt();
app.DebugPrintf("\tcompr_len=%d.\n\tdecomp_len=%d.\n", compr_len,
decomp_len);
// Decompress File Body
std::vector<uint8_t> content(decomp_len);
std::vector<uint8_t> compr_content(compr_len);
dis.read(compr_content);
Compression::getCompression()->SetDecompressionType(
(Compression::ECompressionTypes)compression_type);
unsigned int contentSize = decomp_len;
Compression::getCompression()->DecompressLZXRLE(
content.data(), &contentSize, compr_content.data(),
compr_content.size());
content.resize(contentSize);
Compression::getCompression()->SetDecompressionType(
SAVE_FILE_PLATFORM_LOCAL);
dis.close();
bais.close();
ByteArrayInputStream bais2(content);
DataInputStream dis2(&bais2);
// Read StringTable.
unsigned int bStringTableSize = dis2.readInt();
std::vector<uint8_t> bStringTable(bStringTableSize);
dis2.read(bStringTable);
StringTable* strings =
new StringTable(bStringTable.data(), bStringTable.size());
// Read RuleFile.
std::vector<uint8_t> bRuleFile(content.size() - bStringTable.size());
dis2.read(bRuleFile);
// 4J-JEV: I don't believe that the path-name is ever used.
// DLCGameRulesFile *dlcgr = new DLCGameRulesFile(L"__PLACEHOLDER__");
// dlcgr->addData(bRuleFile.data(),bRuleFile.size());
if (readRuleFile(lgo, bRuleFile.data(), bRuleFile.size(), strings)) {
// Set current gen options and ruleset.
// createdLevelGenerationOptions->setFromSaveGame(true);
lgo->setSrc(LevelGenerationOptions::eSrc_fromSave);
setLevelGenerationOptions(lgo);
// m_currentGameRuleDefinitions = lgo->getRequiredGameRules();
} else {
delete lgo;
}
// Close and return.
dis2.close();
bais2.close();
return;
}
// 4J-JEV: Reverse of loadGameRules.
void GameRuleManager::saveGameRules(uint8_t** dOut, unsigned int* dSize) {
if (m_currentGameRuleDefinitions == nullptr &&
m_currentLevelGenerationOptions == nullptr) {
app.DebugPrintf("GameRuleManager:: Nothing here to save.");
*dOut = nullptr;
*dSize = 0;
return;
}
app.DebugPrintf("GameRuleManager::saveGameRules:\n");
// Initialise output stream.
ByteArrayOutputStream baos;
DataOutputStream dos(&baos);
// Write header.
// VERSION NUMBER
dos.writeShort(0x1); // version_number
// Write 8 bytes of empty space in case we need them later.
// Mainly useful for the ones we save embedded in game saves.
for (unsigned int i = 0; i < 8; i++) dos.writeByte(0x0);
dos.writeByte(APPROPRIATE_COMPRESSION_TYPE); // m_compressionType
// -- START COMPRESSED -- //
ByteArrayOutputStream compr_baos;
DataOutputStream compr_dos(&compr_baos);
if (m_currentGameRuleDefinitions == nullptr) {
compr_dos.writeInt(0); // numStrings for StringTable
compr_dos.writeInt(version_number);
compr_dos.writeByte(
Compression::eCompressionType_None); // compression type
for (int i = 0; i < 2; i++) compr_dos.writeByte(0x0); // Padding.
compr_dos.writeInt(0); // StringLookup.size()
compr_dos.writeInt(0); // SchematicFiles.size()
compr_dos.writeInt(0); // XmlObjects.size()
} else {
StringTable* st = m_currentGameRuleDefinitions->getStringTable();
if (st == nullptr) {
app.DebugPrintf(
"GameRuleManager::saveGameRules: StringTable == nullptr!");
} else {
// Write string table.
uint8_t* stbaPtr = nullptr;
unsigned int stbaSize = 0;
m_currentGameRuleDefinitions->getStringTable()->getData(&stbaPtr,
&stbaSize);
std::vector<uint8_t> stba(stbaPtr, stbaPtr + stbaSize);
compr_dos.writeInt(stba.size());
compr_dos.write(stba);
// Write game rule file to second
// buffer and generate string lookup.
writeRuleFile(&compr_dos);
}
}
// Compress compr_dos and write to dos.
std::vector<uint8_t> compr_ba(compr_baos.buf.size());
unsigned int compr_ba_size = compr_ba.size();
Compression::getCompression()->CompressLZXRLE(
compr_ba.data(), &compr_ba_size, compr_baos.buf.data(),
compr_baos.buf.size());
compr_ba.resize(compr_ba_size);
app.DebugPrintf("\tcompr_ba.size()=%d.\n\tcompr_baos.buf.size()=%d.\n",
compr_ba.size(), compr_baos.buf.size());
dos.writeInt(compr_ba.size()); // Write length
dos.writeInt(compr_baos.buf.size());
dos.write(compr_ba);
compr_dos.close();
compr_baos.close();
// -- END COMPRESSED -- //
// return
*dSize = baos.buf.size();
*dOut = new uint8_t[baos.buf.size()];
memcpy(*dOut, baos.buf.data(), baos.buf.size());
dos.close();
baos.close();
}
// 4J-JEV: Reverse of readRuleFile.
void GameRuleManager::writeRuleFile(DataOutputStream* dos) {
// Write Header
dos->writeShort(version_number); // Version number.
dos->writeByte(Compression::eCompressionType_None); // compression type
for (int i = 0; i < 8; i++) dos->writeBoolean(false); // Padding.
// Write string lookup.
int numStrings = static_cast<int>(ConsoleGameRules::eGameRuleType_Count) +
static_cast<int>(ConsoleGameRules::eGameRuleAttr_Count);
dos->writeInt(numStrings);
for (int i = 0; i < ConsoleGameRules::eGameRuleType_Count; i++)
dos->writeUTF(wchTagNameA[i]);
for (int i = 0; i < ConsoleGameRules::eGameRuleAttr_Count; i++)
dos->writeUTF(wchAttrNameA[i]);
// Write schematic files.
std::unordered_map<std::wstring, ConsoleSchematicFile*>* files;
files = getLevelGenerationOptions()->getUnfinishedSchematicFiles();
dos->writeInt(files->size());
for (auto it = files->begin(); it != files->end(); it++) {
std::wstring filename = it->first;
ConsoleSchematicFile* file = it->second;
ByteArrayOutputStream fileBaos;
DataOutputStream fileDos(&fileBaos);
file->save(&fileDos);
dos->writeUTF(filename);
// dos->writeInt(file->m_data.size());
dos->writeInt(fileBaos.buf.size());
dos->write((std::vector<uint8_t>)fileBaos.buf);
fileDos.close();
fileBaos.close();
}
// Write xml objects.
dos->writeInt(2); // numChildren
m_currentLevelGenerationOptions->write(dos);
m_currentGameRuleDefinitions->write(dos);
}
bool GameRuleManager::readRuleFile(
LevelGenerationOptions* lgo, uint8_t* dIn, unsigned int dSize,
StringTable* strings) //(DLCGameRulesFile *dlcFile, StringTable *strings)
{
bool levelGenAdded = false;
bool gameRulesAdded = false;
LevelGenerationOptions* levelGenerator =
lgo; // new LevelGenerationOptions();
LevelRuleset* gameRules = new LevelRuleset();
// std::uint32_t dataLength = 0;
// std::uint8_t *data = dlcFile->getData(dataLength);
// std::vector<uint8_t> data(pbData,dwLen);
std::vector<uint8_t> data(dIn, dIn + dSize);
ByteArrayInputStream bais(data);
DataInputStream dis(&bais);
// Read File.
// version_number
int64_t version = dis.readShort();
unsigned char compressionType = 0;
if (version == 0) {
for (int i = 0; i < 14; i++) dis.readByte(); // Read padding.
} else {
compressionType = dis.readByte();
// Read the spare bytes we inserted for future use
for (int i = 0; i < 8; ++i) dis.readBoolean();
}
ByteArrayInputStream* contentBais = nullptr;
DataInputStream* contentDis = nullptr;
if (compressionType == Compression::eCompressionType_None) {
// No compression
// No need to read buffer size, as we can read the stream as it is;
app.DebugPrintf("De-compressing game rules with: None\n");
contentDis = &dis;
} else {
unsigned int uncompressedSize = dis.readInt();
unsigned int compressedSize = dis.readInt();
std::vector<uint8_t> compressedBuffer(compressedSize);
dis.read(compressedBuffer);
std::vector<uint8_t> decompressedBuffer =
std::vector<uint8_t>(uncompressedSize);
unsigned int decompressedSize = uncompressedSize;
switch (compressionType) {
case Compression::eCompressionType_None:
memcpy(decompressedBuffer.data(), compressedBuffer.data(),
uncompressedSize);
break;
case Compression::eCompressionType_RLE:
app.DebugPrintf("De-compressing game rules with: RLE\n");
Compression::getCompression()->Decompress(
decompressedBuffer.data(), &decompressedSize,
compressedBuffer.data(), compressedSize);
decompressedBuffer.resize(decompressedSize);
break;
default:
app.DebugPrintf("De-compressing game rules.");
#if !defined(_CONTENT_PACKAGE)
assert(compressionType == APPROPRIATE_COMPRESSION_TYPE);
#endif
// 4J-JEV: DecompressLZXRLE uses the correct platform specific
// compression type. (need to assert that the data is compressed
// with it though).
Compression::getCompression()->DecompressLZXRLE(
decompressedBuffer.data(), &decompressedSize,
compressedBuffer.data(), compressedSize);
decompressedBuffer.resize(decompressedSize);
break;
/* 4J-JEV:
Each platform has only 1 method of compression,
'compression.h' file deals with it.
case Compression::eCompressionType_LZXRLE:
app.DebugPrintf("De-compressing game
rules with: LZX+RLE\n");
Compression::getCompression()->DecompressLZXRLE(
decompressedBuffer.data(), &uncompressedSize,
compressedBuffer.data(), compressedSize); break; default:
app.DebugPrintf("Invalid compression
type %d found\n", compressionType);
__debugbreak();
[] decompressedBuffer.data(); dis.close(); bais.reset();
if(!gameRulesAdded) delete gameRules;
return false;
*/
};
contentBais = new ByteArrayInputStream(decompressedBuffer);
contentDis = new DataInputStream(contentBais);
}
// string lookup.
unsigned int numStrings = contentDis->readInt();
std::vector<std::wstring> tagsAndAtts;
for (unsigned int i = 0; i < numStrings; i++)
tagsAndAtts.push_back(contentDis->readUTF());
std::unordered_map<int, ConsoleGameRules::EGameRuleType> tagIdMap;
for (int type = (int)ConsoleGameRules::eGameRuleType_Root;
type < (int)ConsoleGameRules::eGameRuleType_Count; ++type) {
for (unsigned int i = 0; i < numStrings; ++i) {
if (tagsAndAtts[i].compare(wchTagNameA[type]) == 0) {
tagIdMap.insert(
std::unordered_map<int, ConsoleGameRules::EGameRuleType>::
value_type(i, (ConsoleGameRules::EGameRuleType)type));
break;
}
}
}
// 4J-JEV: TODO: As yet unused.
/*
std::unordered_map<int, ConsoleGameRules::EGameRuleAttr> attrIdMap;
for(int attr = (int)ConsoleGameRules::eGameRuleAttr_descriptionName; attr <
(int)ConsoleGameRules::eGameRuleAttr_Count; ++attr)
{
for (unsigned int i = 0; i < numStrings; i++)
{
if (tagsAndAtts[i].compare(wchAttrNameA[attr]) == 0)
{
tagIdMap.insert( std::unordered_map<int,
ConsoleGameRules::EGameRuleAttr>::value_type(i ,
(ConsoleGameRules::EGameRuleAttr)attr) ); break;
}
}
}*/
// subfile
unsigned int numFiles = contentDis->readInt();
for (unsigned int i = 0; i < numFiles; i++) {
std::wstring sFilename = contentDis->readUTF();
int length = contentDis->readInt();
std::vector<uint8_t> ba(length);
contentDis->read(ba);
levelGenerator->loadSchematicFile(sFilename, ba.data(), ba.size());
}
LEVEL_GEN_ID lgoID = LEVEL_GEN_ID_NULL;
// xml objects
unsigned int numObjects = contentDis->readInt();
for (unsigned int i = 0; i < numObjects; ++i) {
int tagId = contentDis->readInt();
ConsoleGameRules::EGameRuleType tagVal =
ConsoleGameRules::eGameRuleType_Invalid;
auto it = tagIdMap.find(tagId);
if (it != tagIdMap.end()) tagVal = it->second;
GameRuleDefinition* rule = nullptr;
if (tagVal == ConsoleGameRules::eGameRuleType_LevelGenerationOptions) {
rule = levelGenerator;
levelGenAdded = true;
// m_levelGenerators.addLevelGenerator(L"",levelGenerator);
lgoID = addLevelGenerationOptions(levelGenerator);
levelGenerator->loadStringTable(strings);
} else if (tagVal == ConsoleGameRules::eGameRuleType_LevelRules) {
rule = gameRules;
gameRulesAdded = true;
m_levelRules.addLevelRule(L"", gameRules);
levelGenerator->setRequiredGameRules(gameRules);
gameRules->loadStringTable(strings);
}
readAttributes(contentDis, &tagsAndAtts, rule);
readChildren(contentDis, &tagsAndAtts, &tagIdMap, rule);
}
if (compressionType != 0) {
// Not default
contentDis->close();
if (contentBais != nullptr) delete contentBais;
delete contentDis;
}
dis.close();
bais.reset();
// if(!levelGenAdded) { delete levelGenerator; levelGenerator = nullptr; }
if (!gameRulesAdded) delete gameRules;
return true;
// return levelGenerator;
}
LevelGenerationOptions* GameRuleManager::readHeader(DLCGameRulesHeader* grh) {
LevelGenerationOptions* out = new LevelGenerationOptions();
out->setSrc(LevelGenerationOptions::eSrc_fromDLC);
out->setGrSource(grh);
addLevelGenerationOptions(out);
return out;
}
void GameRuleManager::readAttributes(DataInputStream* dis,
std::vector<std::wstring>* tagsAndAtts,
GameRuleDefinition* rule) {
int numAttrs = dis->readInt();
for (unsigned int att = 0; att < static_cast<unsigned int>(numAttrs);
++att) {
int attID = dis->readInt();
std::wstring value = dis->readUTF();
if (rule != nullptr) rule->addAttribute(tagsAndAtts->at(attID), value);
}
}
void GameRuleManager::readChildren(
DataInputStream* dis, std::vector<std::wstring>* tagsAndAtts,
std::unordered_map<int, ConsoleGameRules::EGameRuleType>* tagIdMap,
GameRuleDefinition* rule) {
int numChildren = dis->readInt();
for (unsigned int child = 0; child < static_cast<unsigned int>(numChildren);
++child) {
int tagId = dis->readInt();
ConsoleGameRules::EGameRuleType tagVal =
ConsoleGameRules::eGameRuleType_Invalid;
auto it = tagIdMap->find(tagId);
if (it != tagIdMap->end()) tagVal = it->second;
GameRuleDefinition* childRule = nullptr;
if (rule != nullptr) childRule = rule->addChild(tagVal);
readAttributes(dis, tagsAndAtts, childRule);
readChildren(dis, tagsAndAtts, tagIdMap, childRule);
}
}
void GameRuleManager::processSchematics(LevelChunk* levelChunk) {
if (getLevelGenerationOptions() != nullptr) {
LevelGenerationOptions* levelGenOptions = getLevelGenerationOptions();
levelGenOptions->processSchematics(levelChunk);
}
}
void GameRuleManager::processSchematicsLighting(LevelChunk* levelChunk) {
if (getLevelGenerationOptions() != nullptr) {
LevelGenerationOptions* levelGenOptions = getLevelGenerationOptions();
levelGenOptions->processSchematicsLighting(levelChunk);
}
}
void GameRuleManager::loadDefaultGameRules() {
#if !defined(__linux__)
#if defined(_WINDOWS64)
File packedTutorialFile(L"Windows64Media\\Tutorial\\Tutorial.pck");
if (!packedTutorialFile.exists())
packedTutorialFile = File(L"Windows64\\Tutorial\\Tutorial.pck");
#else
File packedTutorialFile(L"Tutorial\\Tutorial.pck");
#endif
if (loadGameRulesPack(&packedTutorialFile)) {
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(
app.GetString(IDS_PLAY_TUTORIAL));
// m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(L"Tutorial");
m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(
app.GetString(IDS_TUTORIALSAVENAME));
}
#else
std::wstring fpTutorial = L"Tutorial.pck";
if (app.getArchiveFileSize(fpTutorial) >= 0) {
DLCPack* pack = new DLCPack(L"", 0xffffffff);
uint32_t dwFilesProcessed = 0;
if (app.m_dlcManager.readDLCDataFile(dwFilesProcessed, fpTutorial, pack,
true)) {
app.m_dlcManager.addPack(pack);
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(
app.GetString(IDS_PLAY_TUTORIAL));
m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(
app.GetString(IDS_TUTORIALSAVENAME));
} else
delete pack;
}
#endif
}
bool GameRuleManager::loadGameRulesPack(File* path) {
bool success = false;
if (path->exists()) {
DLCPack* pack = new DLCPack(L"", 0xffffffff);
unsigned int dwFilesProcessed = 0;
if (app.m_dlcManager.readDLCDataFile(dwFilesProcessed, path->getPath(),
pack)) {
app.m_dlcManager.addPack(pack);
success = true;
} else {
delete pack;
}
}
return success;
}
void GameRuleManager::setLevelGenerationOptions(
LevelGenerationOptions* levelGen) {
unloadCurrentGameRules();
m_currentGameRuleDefinitions = nullptr;
m_currentLevelGenerationOptions = levelGen;
if (m_currentLevelGenerationOptions != nullptr &&
m_currentLevelGenerationOptions->requiresGameRules()) {
m_currentGameRuleDefinitions =
m_currentLevelGenerationOptions->getRequiredGameRules();
}
if (m_currentLevelGenerationOptions != nullptr)
m_currentLevelGenerationOptions->reset_start();
}
const wchar_t* GameRuleManager::GetGameRulesString(const std::wstring& key) {
if (m_currentGameRuleDefinitions != nullptr && !key.empty()) {
return m_currentGameRuleDefinitions->getString(key);
} else {
return L"";
}
}
LEVEL_GEN_ID GameRuleManager::addLevelGenerationOptions(
LevelGenerationOptions* lgo) {
std::vector<LevelGenerationOptions*>* lgs =
m_levelGenerators.getLevelGenerators();
for (int i = 0; i < lgs->size(); i++)
if (lgs->at(i) == lgo) return i;
lgs->push_back(lgo);
return lgs->size() - 1;
}
void GameRuleManager::unloadCurrentGameRules() {
if (m_currentLevelGenerationOptions != nullptr) {
if (m_currentGameRuleDefinitions != nullptr &&
m_currentLevelGenerationOptions->isFromSave())
m_levelRules.removeLevelRule(m_currentGameRuleDefinitions);
if (m_currentLevelGenerationOptions->isFromSave()) {
m_levelGenerators.removeLevelGenerator(
m_currentLevelGenerationOptions);
delete m_currentLevelGenerationOptions;
} else if (m_currentLevelGenerationOptions->isFromDLC()) {
m_currentLevelGenerationOptions->reset_finish();
}
}
m_currentGameRuleDefinitions = nullptr;
m_currentLevelGenerationOptions = nullptr;
}
@@ -0,0 +1,106 @@
#pragma once
////using namespace std;
#include <stdint.h>
#include <format>
#include <string>
#include <unordered_map>
#include "app/common/src/DLC/DLCGameRulesHeader.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/LevelGenerators.h"
#include "app/common/src/GameRules/LevelRules/LevelRules.h"
class LevelGenerationOptions;
class RootGameRulesDefinition;
class LevelChunk;
class DLCPack;
class DLCGameRulesFile;
// class DLCGameRulesHeader;
class StringTable;
class GameRuleDefinition;
class DataInputStream;
class DataOutputStream;
class WstringLookup;
class DLCGameRulesHeader;
class File;
class LevelRuleset;
#define GAME_RULE_SAVENAME L"requiredGameRules.grf"
// 4J-JEV:
#define LEVEL_GEN_ID int
#define LEVEL_GEN_ID_NULL 0
class GameRuleManager {
public:
static const wchar_t* wchTagNameA[ConsoleGameRules::eGameRuleType_Count];
static const wchar_t* wchAttrNameA[ConsoleGameRules::eGameRuleAttr_Count];
static const short version_number = 2;
private:
LevelGenerationOptions* m_currentLevelGenerationOptions;
LevelRuleset* m_currentGameRuleDefinitions;
LevelGenerators m_levelGenerators;
LevelRules m_levelRules;
public:
GameRuleManager();
void loadGameRules(DLCPack*);
LevelGenerationOptions* loadGameRules(uint8_t* dIn, unsigned int dSize);
void loadGameRules(LevelGenerationOptions* lgo, uint8_t* dIn,
unsigned int dSize);
void saveGameRules(uint8_t** dOut, unsigned int* dSize);
private:
LevelGenerationOptions* readHeader(DLCGameRulesHeader* grh);
void writeRuleFile(DataOutputStream* dos);
public:
bool readRuleFile(LevelGenerationOptions* lgo, uint8_t* dIn,
unsigned int dSize,
StringTable* strings); //(DLCGameRulesFile *dlcFile,
// StringTable *strings);
private:
void readAttributes(DataInputStream* dis,
std::vector<std::wstring>* tagsAndAtts,
GameRuleDefinition* rule);
void readChildren(
DataInputStream* dis, std::vector<std::wstring>* tagsAndAtts,
std::unordered_map<int, ConsoleGameRules::EGameRuleType>* tagIdMap,
GameRuleDefinition* rule);
public:
void processSchematics(LevelChunk* levelChunk);
void processSchematicsLighting(LevelChunk* levelChunk);
void loadDefaultGameRules();
private:
bool loadGameRulesPack(File* path);
LEVEL_GEN_ID addLevelGenerationOptions(LevelGenerationOptions*);
public:
std::vector<LevelGenerationOptions*>* getLevelGenerators() {
return m_levelGenerators.getLevelGenerators();
}
void setLevelGenerationOptions(LevelGenerationOptions* levelGen);
LevelRuleset* getGameRuleDefinitions() {
return m_currentGameRuleDefinitions;
}
LevelGenerationOptions* getLevelGenerationOptions() {
return m_currentLevelGenerationOptions;
}
const wchar_t* GetGameRulesString(const std::wstring& key);
// 4J-JEV:
// Properly cleans-up and unloads the current set of gameRules.
void unloadCurrentGameRules();
};
@@ -0,0 +1,249 @@
#include "ApplySchematicRuleDefinition.h"
#include <algorithm>
#include <cmath>
#include "ConsoleSchematicFile.h"
#include "LevelGenerationOptions.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/chunk/LevelChunk.h"
#include "minecraft/world/level/dimension/Dimension.h"
#include "minecraft/world/phys/AABB.h"
ApplySchematicRuleDefinition::ApplySchematicRuleDefinition(
LevelGenerationOptions* levelGenOptions) {
m_levelGenOptions = levelGenOptions;
m_location = Vec3(0, 0, 0);
m_locationBox = std::nullopt;
m_totalBlocksChanged = 0;
m_totalBlocksChangedLighting = 0;
m_rotation = ConsoleSchematicFile::eSchematicRot_0;
m_completed = false;
m_dimension = 0;
m_schematic = nullptr;
}
ApplySchematicRuleDefinition::~ApplySchematicRuleDefinition() {
app.DebugPrintf("Deleting ApplySchematicRuleDefinition.\n");
if (!m_completed) m_levelGenOptions->releaseSchematicFile(m_schematicName);
m_schematic = nullptr;
}
void ApplySchematicRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_filename);
dos->writeUTF(m_schematicName);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x);
dos->writeUTF(_toString(m_location.x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y);
dos->writeUTF(_toString(m_location.y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z);
dos->writeUTF(_toString(m_location.z));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_rot);
switch (m_rotation) {
case ConsoleSchematicFile::eSchematicRot_0:
dos->writeUTF(_toString(0));
break;
case ConsoleSchematicFile::eSchematicRot_90:
dos->writeUTF(_toString(90));
break;
case ConsoleSchematicFile::eSchematicRot_180:
dos->writeUTF(_toString(180));
break;
case ConsoleSchematicFile::eSchematicRot_270:
dos->writeUTF(_toString(270));
break;
}
}
void ApplySchematicRuleDefinition::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"filename") == 0) {
m_schematicName = attributeValue;
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// filename=%s\n",m_schematicName.c_str());
if (!m_schematicName.empty()) {
if (m_schematicName
.substr(m_schematicName.length() - 4,
m_schematicName.length())
.compare(L".sch") != 0) {
m_schematicName.append(L".sch");
}
m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
}
} else if (attributeName.compare(L"x") == 0) {
m_location.x = _fromString<int>(attributeValue);
if (((int)std::abs(m_location.x)) % 2 != 0) m_location.x -= 1;
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// x=%f\n",m_location->x);
} else if (attributeName.compare(L"y") == 0) {
m_location.y = _fromString<int>(attributeValue);
if (((int)std::abs(m_location.y)) % 2 != 0) m_location.y -= 1;
if (m_location.y < 0) m_location.y = 0;
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// y=%f\n",m_location->y);
} else if (attributeName.compare(L"z") == 0) {
m_location.z = _fromString<int>(attributeValue);
if (((int)std::abs(m_location.z)) % 2 != 0) m_location.z -= 1;
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// z=%f\n",m_location->z);
} else if (attributeName.compare(L"rot") == 0) {
int degrees = _fromString<int>(attributeValue);
while (degrees < 0) degrees += 360;
while (degrees >= 360) degrees -= 360;
float quad = degrees / 90;
degrees = (int)(quad + 0.5f);
switch (degrees) {
case 1:
m_rotation = ConsoleSchematicFile::eSchematicRot_90;
break;
case 2:
m_rotation = ConsoleSchematicFile::eSchematicRot_180;
break;
case 3:
case 4:
m_rotation = ConsoleSchematicFile::eSchematicRot_270;
break;
case 0:
default:
m_rotation = ConsoleSchematicFile::eSchematicRot_0;
break;
};
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// rot=%d\n",m_rotation);
} else if (attributeName.compare(L"dim") == 0) {
m_dimension = _fromString<int>(attributeValue);
if (m_dimension > 1 || m_dimension < -1) m_dimension = 0;
// app.DebugPrintf("ApplySchematicRuleDefinition: Adding parameter
// dimension=%d\n",m_dimension);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
void ApplySchematicRuleDefinition::updateLocationBox() {
if (m_schematic == nullptr)
m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
m_locationBox = AABB(0, 0, 0, 0, 0, 0);
m_locationBox->x0 = m_location.x;
m_locationBox->y0 = m_location.y;
m_locationBox->z0 = m_location.z;
m_locationBox->y1 = m_location.y + m_schematic->getYSize();
switch (m_rotation) {
case ConsoleSchematicFile::eSchematicRot_90:
case ConsoleSchematicFile::eSchematicRot_270:
m_locationBox->x1 = m_location.x + m_schematic->getZSize();
m_locationBox->z1 = m_location.z + m_schematic->getXSize();
break;
case ConsoleSchematicFile::eSchematicRot_0:
case ConsoleSchematicFile::eSchematicRot_180:
default:
m_locationBox->x1 = m_location.x + m_schematic->getXSize();
m_locationBox->z1 = m_location.z + m_schematic->getZSize();
break;
};
}
void ApplySchematicRuleDefinition::processSchematic(AABB* chunkBox,
LevelChunk* chunk) {
if (m_completed) return;
if (chunk->level->dimension->id != m_dimension) return;
if (m_schematic == nullptr)
m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
if (!m_locationBox.has_value()) updateLocationBox();
if (chunkBox->intersects(*m_locationBox)) {
m_locationBox->y1 =
std::min((double)Level::maxBuildHeight, m_locationBox->y1);
#ifdef _DEBUG
app.DebugPrintf("Applying schematic %ls to chunk (%d,%d)\n",
m_schematicName.c_str(), chunk->x, chunk->z);
#endif
m_totalBlocksChanged += m_schematic->applyBlocksAndData(
chunk, chunkBox, &*m_locationBox, m_rotation);
// Add the tileEntities
m_schematic->applyTileEntities(chunk, chunkBox, &*m_locationBox,
m_rotation);
// TODO This does not take into account things that go outside the
// bounds of the world
int targetBlocks = (m_locationBox->x1 - m_locationBox->x0) *
(m_locationBox->y1 - m_locationBox->y0) *
(m_locationBox->z1 - m_locationBox->z0);
if ((m_totalBlocksChanged == targetBlocks) &&
(m_totalBlocksChangedLighting == targetBlocks)) {
m_completed = true;
// m_levelGenOptions->releaseSchematicFile(m_schematicName);
// m_schematic = nullptr;
}
}
}
void ApplySchematicRuleDefinition::processSchematicLighting(AABB* chunkBox,
LevelChunk* chunk) {
if (m_completed) return;
if (chunk->level->dimension->id != m_dimension) return;
if (m_schematic == nullptr)
m_schematic = m_levelGenOptions->getSchematicFile(m_schematicName);
if (!m_locationBox.has_value()) updateLocationBox();
if (chunkBox->intersects(*m_locationBox)) {
m_locationBox->y1 =
std::min((double)Level::maxBuildHeight, m_locationBox->y1);
#ifdef _DEBUG
app.DebugPrintf("Applying schematic %ls to chunk (%d,%d)\n",
m_schematicName.c_str(), chunk->x, chunk->z);
#endif
m_totalBlocksChangedLighting += m_schematic->applyLighting(
chunk, chunkBox, &*m_locationBox, m_rotation);
// TODO This does not take into account things that go outside the
// bounds of the world
int targetBlocks = (m_locationBox->x1 - m_locationBox->x0) *
(m_locationBox->y1 - m_locationBox->y0) *
(m_locationBox->z1 - m_locationBox->z0);
if ((m_totalBlocksChanged == targetBlocks) &&
(m_totalBlocksChangedLighting == targetBlocks)) {
m_completed = true;
// m_levelGenOptions->releaseSchematicFile(m_schematicName);
// m_schematic = nullptr;
}
}
}
bool ApplySchematicRuleDefinition::checkIntersects(int x0, int y0, int z0,
int x1, int y1, int z1) {
if (!m_locationBox.has_value()) updateLocationBox();
return m_locationBox->intersects(x0, y0, z0, x1, y1, z1);
}
int ApplySchematicRuleDefinition::getMinY() {
if (!m_locationBox.has_value()) updateLocationBox();
return m_locationBox->y0;
}
void ApplySchematicRuleDefinition::reset() {
m_totalBlocksChanged = 0;
m_totalBlocksChangedLighting = 0;
m_completed = false;
}
@@ -0,0 +1,62 @@
#pragma once
#include <stdint.h>
#include <optional>
#include <string>
#include "ConsoleSchematicFile.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "minecraft/world/phys/AABB.h"
#include "minecraft/world/phys/Vec3.h"
class AABB;
class Vec3;
class LevelChunk;
class LevelGenerationOptions;
class GRFObject;
class ApplySchematicRuleDefinition : public GameRuleDefinition {
private:
LevelGenerationOptions* m_levelGenOptions;
std::wstring m_schematicName;
ConsoleSchematicFile* m_schematic;
Vec3 m_location;
std::optional<AABB> m_locationBox;
ConsoleSchematicFile::ESchematicRotation m_rotation;
int m_dimension;
int64_t m_totalBlocksChanged;
int64_t m_totalBlocksChangedLighting;
bool m_completed;
void updateLocationBox();
public:
ApplySchematicRuleDefinition(LevelGenerationOptions* levelGenOptions);
~ApplySchematicRuleDefinition();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_ApplySchematic;
}
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
void processSchematic(AABB* chunkBox, LevelChunk* chunk);
void processSchematicLighting(AABB* chunkBox, LevelChunk* chunk);
bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1);
int getMinY();
bool isComplete() { return m_completed; }
std::wstring getSchematicName() { return m_schematicName; }
/** 4J-JEV:
* This GameRuleDefinition contains limited game state.
* Reset any state to how it should be before a new game.
*/
void reset();
};
@@ -0,0 +1,53 @@
#include "BiomeOverride.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
BiomeOverride::BiomeOverride() {
m_tile = 0;
m_topTile = 0;
m_biomeId = 0;
}
void BiomeOverride::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 3);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_biomeId);
dos->writeUTF(_toString(m_biomeId));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_tileId);
dos->writeUTF(_toString(m_tile));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_topTileId);
dos->writeUTF(_toString(m_topTile));
}
void BiomeOverride::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"tileId") == 0) {
int value = _fromString<int>(attributeValue);
m_tile = value;
app.DebugPrintf("BiomeOverride: Adding parameter tileId=%d\n", m_tile);
} else if (attributeName.compare(L"topTileId") == 0) {
int value = _fromString<int>(attributeValue);
m_topTile = value;
app.DebugPrintf("BiomeOverride: Adding parameter topTileId=%d\n",
m_topTile);
} else if (attributeName.compare(L"biomeId") == 0) {
int value = _fromString<int>(attributeValue);
m_biomeId = value;
app.DebugPrintf("BiomeOverride: Adding parameter biomeId=%d\n",
m_biomeId);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool BiomeOverride::isBiome(int id) { return m_biomeId == id; }
void BiomeOverride::getTileValues(std::uint8_t& tile, std::uint8_t& topTile) {
if (m_tile != 0) tile = m_tile;
if (m_topTile != 0) topTile = m_topTile;
}
@@ -0,0 +1,29 @@
#pragma once
// using namespace std;
#include <cstdint>
#include <string>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
class BiomeOverride : public GameRuleDefinition {
private:
std::uint8_t m_topTile;
std::uint8_t m_tile;
int m_biomeId;
public:
BiomeOverride();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_BiomeOverride;
}
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool isBiome(int id);
void getTileValues(std::uint8_t& tile, std::uint8_t& topTile);
};
@@ -0,0 +1,173 @@
#include "ConsoleGenerateStructure.h"
#include <wchar.h>
#include <algorithm>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionGenerateBox.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceBlock.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceContainer.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceSpawner.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/Direction.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/dimension/Dimension.h"
#include "minecraft/world/level/levelgen/structure/BoundingBox.h"
ConsoleGenerateStructure::ConsoleGenerateStructure() : StructurePiece(0) {
m_x = m_y = m_z = 0;
boundingBox = nullptr;
orientation = Direction::NORTH;
m_dimension = 0;
}
void ConsoleGenerateStructure::getChildren(
std::vector<GameRuleDefinition*>* children) {
GameRuleDefinition::getChildren(children);
for (auto it = m_actions.begin(); it != m_actions.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* ConsoleGenerateStructure::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_GenerateBox) {
rule = new XboxStructureActionGenerateBox();
m_actions.push_back((XboxStructureActionGenerateBox*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_PlaceBlock) {
rule = new XboxStructureActionPlaceBlock();
m_actions.push_back((XboxStructureActionPlaceBlock*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_PlaceContainer) {
rule = new XboxStructureActionPlaceContainer();
m_actions.push_back((XboxStructureActionPlaceContainer*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_PlaceSpawner) {
rule = new XboxStructureActionPlaceSpawner();
m_actions.push_back((XboxStructureActionPlaceSpawner*)rule);
} else {
#ifndef _CONTENT_PACKAGE
wprintf(
L"ConsoleGenerateStructure: Attempted to add invalid child rule - "
L"%d\n",
ruleType);
#endif
}
return rule;
}
void ConsoleGenerateStructure::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x);
dos->writeUTF(_toString(m_x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y);
dos->writeUTF(_toString(m_y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z);
dos->writeUTF(_toString(m_z));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_orientation);
dos->writeUTF(_toString(orientation));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_dimension);
dos->writeUTF(_toString(m_dimension));
}
void ConsoleGenerateStructure::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"x") == 0) {
int value = _fromString<int>(attributeValue);
m_x = value;
app.DebugPrintf("ConsoleGenerateStructure: Adding parameter x=%d\n",
m_x);
} else if (attributeName.compare(L"y") == 0) {
int value = _fromString<int>(attributeValue);
m_y = value;
app.DebugPrintf("ConsoleGenerateStructure: Adding parameter y=%d\n",
m_y);
} else if (attributeName.compare(L"z") == 0) {
int value = _fromString<int>(attributeValue);
m_z = value;
app.DebugPrintf("ConsoleGenerateStructure: Adding parameter z=%d\n",
m_z);
} else if (attributeName.compare(L"orientation") == 0) {
int value = _fromString<int>(attributeValue);
orientation = value;
app.DebugPrintf(
"ConsoleGenerateStructure: Adding parameter orientation=%d\n",
orientation);
} else if (attributeName.compare(L"dim") == 0) {
m_dimension = _fromString<int>(attributeValue);
if (m_dimension > 1 || m_dimension < -1) m_dimension = 0;
app.DebugPrintf(
"ApplySchematicRuleDefinition: Adding parameter dimension=%d\n",
m_dimension);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
BoundingBox* ConsoleGenerateStructure::getBoundingBox() {
if (boundingBox == nullptr) {
// Find the max bounds
int maxX, maxY, maxZ;
maxX = maxY = maxZ = 1;
for (auto it = m_actions.begin(); it != m_actions.end(); ++it) {
ConsoleGenerateStructureAction* action = *it;
maxX = std::max(maxX, action->getEndX());
maxY = std::max(maxY, action->getEndY());
maxZ = std::max(maxZ, action->getEndZ());
}
boundingBox =
new BoundingBox(m_x, m_y, m_z, m_x + maxX, m_y + maxY, m_z + maxZ);
}
return boundingBox;
}
bool ConsoleGenerateStructure::postProcess(Level* level, Random* random,
BoundingBox* chunkBB) {
if (level->dimension->id != m_dimension) return false;
for (auto it = m_actions.begin(); it != m_actions.end(); ++it) {
ConsoleGenerateStructureAction* action = *it;
switch (action->getActionType()) {
case ConsoleGameRules::eGameRuleType_GenerateBox: {
XboxStructureActionGenerateBox* genBox =
(XboxStructureActionGenerateBox*)action;
genBox->generateBoxInLevel(this, level, chunkBB);
} break;
case ConsoleGameRules::eGameRuleType_PlaceBlock: {
XboxStructureActionPlaceBlock* pPlaceBlock =
(XboxStructureActionPlaceBlock*)action;
pPlaceBlock->placeBlockInLevel(this, level, chunkBB);
} break;
case ConsoleGameRules::eGameRuleType_PlaceContainer: {
XboxStructureActionPlaceContainer* pPlaceContainer =
(XboxStructureActionPlaceContainer*)action;
pPlaceContainer->placeContainerInLevel(this, level, chunkBB);
} break;
case ConsoleGameRules::eGameRuleType_PlaceSpawner: {
XboxStructureActionPlaceSpawner* pPlaceSpawner =
(XboxStructureActionPlaceSpawner*)action;
pPlaceSpawner->placeSpawnerInLevel(this, level, chunkBB);
} break;
default:
break;
};
}
return false;
}
bool ConsoleGenerateStructure::checkIntersects(int x0, int y0, int z0, int x1,
int y1, int z1) {
return getBoundingBox()->intersects(x0, y0, z0, x1, y1, z1);
}
int ConsoleGenerateStructure::getMinY() { return getBoundingBox()->y0; }
@@ -0,0 +1,54 @@
#pragma once
#include <string>
#include <vector>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "minecraft/world/level/levelgen/structure/StructureFeatureIO.h"
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
class Level;
class Random;
class BoundingBox;
class ConsoleGenerateStructureAction;
class XboxStructureActionPlaceContainer;
class GRFObject;
class ConsoleGenerateStructure : public GameRuleDefinition,
public StructurePiece {
private:
int m_x, m_y, m_z;
std::vector<ConsoleGenerateStructureAction*> m_actions;
int m_dimension;
public:
ConsoleGenerateStructure();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_GenerateStructure;
}
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
// StructurePiece
virtual BoundingBox* getBoundingBox();
virtual bool postProcess(Level* level, Random* random,
BoundingBox* chunkBB);
void createContainer(XboxStructureActionPlaceContainer* action,
Level* level, BoundingBox* chunkBB);
bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1);
virtual int getMinY();
EStructurePiece GetType() { return (EStructurePiece)0; }
void addAdditonalSaveData(CompoundTag* tag) {}
void readAdditonalSaveData(CompoundTag* tag) {}
};
@@ -0,0 +1,10 @@
#pragma once
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
class ConsoleGenerateStructureAction : public GameRuleDefinition {
public:
virtual int getEndX() = 0;
virtual int getEndY() = 0;
virtual int getEndZ() = 0;
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,121 @@
#pragma once
// using namespace std;
#define XBOX_SCHEMATIC_ORIGINAL_VERSION 1
#define XBOX_SCHEMATIC_CURRENT_VERSION 2
#include <stdint.h>
#include <string.h>
#include <format>
#include <memory>
#include <ranges>
#include <utility>
#include <vector>
#include "app/linux/Stubs/winapi_stubs.h"
#include "console_helpers/compression.h"
#include "minecraft/world/phys/Vec3.h"
class Level;
class DataOutputStream;
class DataInputStream;
class TileEntity;
class LevelChunk;
class AABB;
class Vec3;
class CompoundTag;
class ConsoleSchematicFile {
public:
enum ESchematicRotation {
eSchematicRot_0,
eSchematicRot_90,
eSchematicRot_180,
eSchematicRot_270
};
private:
int m_refCount;
public:
void incrementRefCount() { ++m_refCount; }
void decrementRefCount() { --m_refCount; }
bool shouldDelete() { return m_refCount <= 0; }
typedef struct _XboxSchematicInitParam {
wchar_t name[64];
int startX;
int startY;
int startZ;
int endX;
int endY;
int endZ;
bool bSaveMobs;
Compression::ECompressionTypes compressionType;
_XboxSchematicInitParam() {
memset(name, 0, 64 * (sizeof(wchar_t)));
startX = startY = startZ = endX = endY = endZ = 0;
bSaveMobs = false;
compressionType = Compression::eCompressionType_None;
}
} XboxSchematicInitParam;
private:
int m_xSize, m_ySize, m_zSize;
std::vector<std::shared_ptr<TileEntity> > m_tileEntities;
std::vector<std::pair<Vec3, CompoundTag*> > m_entities;
public:
std::vector<uint8_t> m_data;
public:
ConsoleSchematicFile();
~ConsoleSchematicFile();
int getXSize() { return m_xSize; }
int getYSize() { return m_ySize; }
int getZSize() { return m_zSize; }
void save(DataOutputStream* dos);
void load(DataInputStream* dis);
int64_t applyBlocksAndData(LevelChunk* chunk, AABB* chunkBox,
AABB* destinationBox, ESchematicRotation rot);
int64_t applyLighting(LevelChunk* chunk, AABB* chunkBox,
AABB* destinationBox, ESchematicRotation rot);
void applyTileEntities(LevelChunk* chunk, AABB* chunkBox,
AABB* destinationBox, ESchematicRotation rot);
static void generateSchematicFile(DataOutputStream* dos, Level* level,
int xStart, int yStart, int zStart,
int xEnd, int yEnd, int zEnd,
bool bSaveMobs,
Compression::ECompressionTypes);
static void setBlocksAndData(LevelChunk* chunk,
std::vector<uint8_t>& blockData,
std::vector<uint8_t>& dataData,
std::vector<uint8_t> data, int x0, int y0,
int z0, int x1, int y1, int z1, int& blocksP,
int& dataP, int& blockLightP, int& skyLightP);
private:
void save_tags(DataOutputStream* dos);
void load_tags(DataInputStream* dis);
static void getBlocksAndData(LevelChunk* chunk, std::vector<uint8_t>* data,
int x0, int y0, int z0, int x1, int y1, int z1,
int& blocksP, int& dataP, int& blockLightP,
int& skyLightP);
static std::vector<std::shared_ptr<TileEntity> >* getTileEntitiesInRegion(
LevelChunk* chunk, int x0, int y0, int z0, int x1, int y1, int z1);
void chunkCoordToSchematicCoord(AABB* destinationBox, int chunkX,
int chunkZ, ESchematicRotation rot,
int& schematicX, int& schematicZ);
void schematicCoordToChunkCoord(AABB* destinationBox, double schematicX,
double schematicZ, ESchematicRotation rot,
double& chunkX, double& chunkZ);
};
@@ -0,0 +1,722 @@
#include "LevelGenerationOptions.h"
#include <limits.h>
#include <wchar.h>
#include <filesystem>
#include <fstream>
#include <unordered_set>
#include <utility>
#include "platform/sdl2/Profile.h"
#include "platform/sdl2/Storage.h"
#include "app/common/App_enums.h"
#include "app/common/src/DLC/DLCGameRulesHeader.h"
#include "app/common/src/DLC/DLCManager.h"
#include "app/common/src/DLC/DLCPack.h"
#include "app/common/src/GameRules/GameRuleManager.h"
#include "app/common/src/GameRules/LevelGeneration/ApplySchematicRuleDefinition.h"
#include "app/common/src/GameRules/LevelGeneration/BiomeOverride.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructure.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleSchematicFile.h"
#include "app/common/src/GameRules/LevelGeneration/StartFeature.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/Localisation/StringTable.h"
#include "app/linux/Linux_App.h"
#include "app/linux/Stubs/winapi_stubs.h"
#include "console_helpers/StringHelpers.h"
#include "java/File.h"
#include "java/InputOutputStream/ByteArrayInputStream.h"
#include "java/InputOutputStream/DataInputStream.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/Pos.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/chunk/LevelChunk.h"
#include "minecraft/world/level/levelgen/structure/BoundingBox.h"
#include "minecraft/world/phys/AABB.h"
#include "strings.h"
JustGrSource::JustGrSource() {
m_displayName = L"Default_DisplayName";
m_worldName = L"Default_WorldName";
m_defaultSaveName = L"Default_DefaultSaveName";
m_bRequiresTexturePack = false;
m_requiredTexturePackId = 0;
m_grfPath = L"__NO_GRF_PATH__";
m_bRequiresBaseSave = false;
}
bool JustGrSource::requiresTexturePack() { return m_bRequiresTexturePack; }
std::uint32_t JustGrSource::getRequiredTexturePackId() {
return m_requiredTexturePackId;
}
std::wstring JustGrSource::getDefaultSaveName() { return m_defaultSaveName; }
const wchar_t* JustGrSource::getWorldName() { return m_worldName.c_str(); }
const wchar_t* JustGrSource::getDisplayName() { return m_displayName.c_str(); }
std::wstring JustGrSource::getGrfPath() { return m_grfPath; }
bool JustGrSource::requiresBaseSave() { return m_bRequiresBaseSave; };
std::wstring JustGrSource::getBaseSavePath() { return m_baseSavePath; };
void JustGrSource::setRequiresTexturePack(bool x) {
m_bRequiresTexturePack = x;
}
void JustGrSource::setRequiredTexturePackId(std::uint32_t x) {
m_requiredTexturePackId = x;
}
void JustGrSource::setDefaultSaveName(const std::wstring& x) {
m_defaultSaveName = x;
}
void JustGrSource::setWorldName(const std::wstring& x) { m_worldName = x; }
void JustGrSource::setDisplayName(const std::wstring& x) { m_displayName = x; }
void JustGrSource::setGrfPath(const std::wstring& x) { m_grfPath = x; }
void JustGrSource::setBaseSavePath(const std::wstring& x) {
m_baseSavePath = x;
m_bRequiresBaseSave = true;
}
bool JustGrSource::ready() { return true; }
LevelGenerationOptions::LevelGenerationOptions(DLCPack* parentPack) {
m_spawnPos = nullptr;
m_stringTable = nullptr;
m_hasLoadedData = false;
m_seed = 0;
m_bHasBeenInCreative = true;
m_useFlatWorld = false;
m_bHaveMinY = false;
m_minY = INT_MAX;
m_bRequiresGameRules = false;
m_pbBaseSaveData = nullptr;
m_baseSaveSize = 0;
m_parentDLCPack = parentPack;
m_bLoadingData = false;
}
LevelGenerationOptions::~LevelGenerationOptions() {
clearSchematics();
if (m_spawnPos != nullptr) delete m_spawnPos;
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
++it) {
delete *it;
}
for (auto it = m_structureRules.begin(); it != m_structureRules.end();
++it) {
delete *it;
}
for (auto it = m_biomeOverrides.begin(); it != m_biomeOverrides.end();
++it) {
delete *it;
}
for (auto it = m_features.begin(); it != m_features.end(); ++it) {
delete *it;
}
if (m_stringTable)
if (!isTutorial()) delete m_stringTable;
if (isFromSave()) delete m_pSrc;
}
ConsoleGameRules::EGameRuleType LevelGenerationOptions::getActionType() {
return ConsoleGameRules::eGameRuleType_LevelGenerationOptions;
}
void LevelGenerationOptions::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnX);
dos->writeUTF(_toString(m_spawnPos->x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnY);
dos->writeUTF(_toString(m_spawnPos->y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnZ);
dos->writeUTF(_toString(m_spawnPos->z));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_seed);
dos->writeUTF(_toString(m_seed));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_flatworld);
dos->writeUTF(_toString(m_useFlatWorld));
}
void LevelGenerationOptions::getChildren(
std::vector<GameRuleDefinition*>* children) {
GameRuleDefinition::getChildren(children);
std::vector<ApplySchematicRuleDefinition*> used_schematics;
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end(); it++)
if (!(*it)->isComplete()) used_schematics.push_back(*it);
for (auto it = m_structureRules.begin(); it != m_structureRules.end(); it++)
children->push_back(*it);
for (auto it = used_schematics.begin(); it != used_schematics.end(); it++)
children->push_back(*it);
for (auto it = m_biomeOverrides.begin(); it != m_biomeOverrides.end(); ++it)
children->push_back(*it);
for (auto it = m_features.begin(); it != m_features.end(); ++it)
children->push_back(*it);
}
GameRuleDefinition* LevelGenerationOptions::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_ApplySchematic) {
rule = new ApplySchematicRuleDefinition(this);
m_schematicRules.push_back((ApplySchematicRuleDefinition*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_GenerateStructure) {
rule = new ConsoleGenerateStructure();
m_structureRules.push_back((ConsoleGenerateStructure*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_BiomeOverride) {
rule = new BiomeOverride();
m_biomeOverrides.push_back((BiomeOverride*)rule);
} else if (ruleType == ConsoleGameRules::eGameRuleType_StartFeature) {
rule = new StartFeature();
m_features.push_back((StartFeature*)rule);
} else {
#if !defined(_CONTENT_PACKAGE)
wprintf(
L"LevelGenerationOptions: Attempted to add invalid child rule - "
L"%d\n",
ruleType);
#endif
}
return rule;
}
void LevelGenerationOptions::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"seed") == 0) {
m_seed = _fromString<int64_t>(attributeValue);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter m_seed=%I64d\n", m_seed);
} else if (attributeName.compare(L"spawnX") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->x = value;
app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnX=%d\n",
value);
} else if (attributeName.compare(L"spawnY") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->y = value;
app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnY=%d\n",
value);
} else if (attributeName.compare(L"spawnZ") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->z = value;
app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnZ=%d\n",
value);
} else if (attributeName.compare(L"flatworld") == 0) {
if (attributeValue.compare(L"true") == 0) m_useFlatWorld = true;
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter flatworld=%s\n",
m_useFlatWorld ? "true" : "false");
} else if (attributeName.compare(L"saveName") == 0) {
std::wstring string(getString(attributeValue));
if (!string.empty())
setDefaultSaveName(string);
else
setDefaultSaveName(attributeValue);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter saveName=%ls\n",
getDefaultSaveName().c_str());
} else if (attributeName.compare(L"worldName") == 0) {
std::wstring string(getString(attributeValue));
if (!string.empty())
setWorldName(string);
else
setWorldName(attributeValue);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter worldName=%ls\n",
getWorldName());
} else if (attributeName.compare(L"displayName") == 0) {
std::wstring string(getString(attributeValue));
if (!string.empty())
setDisplayName(string);
else
setDisplayName(attributeValue);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter displayName=%ls\n",
getDisplayName());
} else if (attributeName.compare(L"texturePackId") == 0) {
setRequiredTexturePackId(_fromString<unsigned int>(attributeValue));
setRequiresTexturePack(true);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter texturePackId=%0x\n",
getRequiredTexturePackId());
} else if (attributeName.compare(L"isTutorial") == 0) {
if (attributeValue.compare(L"true") == 0) setSrc(eSrc_tutorial);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter isTutorial=%s\n",
isTutorial() ? "true" : "false");
} else if (attributeName.compare(L"baseSaveName") == 0) {
setBaseSavePath(attributeValue);
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter baseSaveName=%ls\n",
getBaseSavePath().c_str());
} else if (attributeName.compare(L"hasBeenInCreative") == 0) {
bool value = _fromString<bool>(attributeValue);
m_bHasBeenInCreative = value;
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter gameMode=%d\n",
m_bHasBeenInCreative);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
void LevelGenerationOptions::processSchematics(LevelChunk* chunk) {
AABB chunkBox(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16,
Level::maxBuildHeight, chunk->z * 16 + 16);
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
++it) {
ApplySchematicRuleDefinition* rule = *it;
rule->processSchematic(&chunkBox, chunk);
}
int cx = (chunk->x << 4);
int cz = (chunk->z << 4);
for (auto it = m_structureRules.begin(); it != m_structureRules.end();
it++) {
ConsoleGenerateStructure* structureStart = *it;
if (structureStart->getBoundingBox()->intersects(cx, cz, cx + 15,
cz + 15)) {
BoundingBox* bb = new BoundingBox(cx, cz, cx + 15, cz + 15);
structureStart->postProcess(chunk->level, nullptr, bb);
delete bb;
}
}
}
void LevelGenerationOptions::processSchematicsLighting(LevelChunk* chunk) {
AABB chunkBox(chunk->x * 16, 0, chunk->z * 16, chunk->x * 16 + 16,
Level::maxBuildHeight, chunk->z * 16 + 16);
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
++it) {
ApplySchematicRuleDefinition* rule = *it;
rule->processSchematicLighting(&chunkBox, chunk);
}
}
bool LevelGenerationOptions::checkIntersects(int x0, int y0, int z0, int x1,
int y1, int z1) {
// As an optimisation, we can quickly discard things below a certain y which
// makes most ore checks faster due to a) ores generally being below
// ground/sea level and b) tutorial world additions generally being above
// ground/sea level
if (!m_bHaveMinY) {
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
++it) {
ApplySchematicRuleDefinition* rule = *it;
int minY = rule->getMinY();
if (minY < m_minY) m_minY = minY;
}
for (auto it = m_structureRules.begin(); it != m_structureRules.end();
it++) {
ConsoleGenerateStructure* structureStart = *it;
int minY = structureStart->getMinY();
if (minY < m_minY) m_minY = minY;
}
m_bHaveMinY = true;
}
// 4J Stu - We DO NOT intersect if our upper bound is below the lower bound
// for all schematics
if (y1 < m_minY) return false;
bool intersects = false;
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
++it) {
ApplySchematicRuleDefinition* rule = *it;
intersects = rule->checkIntersects(x0, y0, z0, x1, y1, z1);
if (intersects) break;
}
if (!intersects) {
for (auto it = m_structureRules.begin(); it != m_structureRules.end();
it++) {
ConsoleGenerateStructure* structureStart = *it;
intersects =
structureStart->checkIntersects(x0, y0, z0, x1, y1, z1);
if (intersects) break;
}
}
return intersects;
}
void LevelGenerationOptions::clearSchematics() {
for (auto it = m_schematics.begin(); it != m_schematics.end(); ++it) {
delete it->second;
}
m_schematics.clear();
}
ConsoleSchematicFile* LevelGenerationOptions::loadSchematicFile(
const std::wstring& filename, std::uint8_t* pbData,
unsigned int dataLength) {
// If we have already loaded this, just return
auto it = m_schematics.find(filename);
if (it != m_schematics.end()) {
#if !defined(_CONTENT_PACKAGE)
wprintf(L"We have already loaded schematic file %ls\n",
filename.c_str());
#endif
it->second->incrementRefCount();
return it->second;
}
ConsoleSchematicFile* schematic = nullptr;
std::vector<uint8_t> data(pbData, pbData + dataLength);
ByteArrayInputStream bais(data);
DataInputStream dis(&bais);
schematic = new ConsoleSchematicFile();
schematic->load(&dis);
m_schematics[filename] = schematic;
bais.reset();
return schematic;
}
ConsoleSchematicFile* LevelGenerationOptions::getSchematicFile(
const std::wstring& filename) {
ConsoleSchematicFile* schematic = nullptr;
// If we have already loaded this, just return
auto it = m_schematics.find(filename);
if (it != m_schematics.end()) {
schematic = it->second;
}
return schematic;
}
void LevelGenerationOptions::releaseSchematicFile(
const std::wstring& filename) {
// 4J Stu - We don't want to delete them when done, but probably want to
// keep a set of active schematics for the current world
// auto it = m_schematics.find(filename);
// if(it != m_schematics.end())
//{
// ConsoleSchematicFile *schematic = it->second;
// schematic->decrementRefCount();
// if(schematic->shouldDelete())
// {
// delete schematic;
// m_schematics.erase(it);
// }
//}
}
void LevelGenerationOptions::loadStringTable(StringTable* table) {
m_stringTable = table;
}
const wchar_t* LevelGenerationOptions::getString(const std::wstring& key) {
if (m_stringTable == nullptr) {
return L"";
} else {
return m_stringTable->getString(key);
}
}
void LevelGenerationOptions::getBiomeOverride(int biomeId, std::uint8_t& tile,
std::uint8_t& topTile) {
for (auto it = m_biomeOverrides.begin(); it != m_biomeOverrides.end();
++it) {
BiomeOverride* bo = *it;
if (bo->isBiome(biomeId)) {
bo->getTileValues(tile, topTile);
break;
}
}
}
bool LevelGenerationOptions::isFeatureChunk(
int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature,
int* orientation) {
bool isFeature = false;
for (auto it = m_features.begin(); it != m_features.end(); ++it) {
StartFeature* sf = *it;
if (sf->isFeatureChunk(chunkX, chunkZ, feature, orientation)) {
isFeature = true;
break;
}
}
return isFeature;
}
std::unordered_map<std::wstring, ConsoleSchematicFile*>*
LevelGenerationOptions::getUnfinishedSchematicFiles() {
// Clean schematic rules.
std::unordered_set<std::wstring> usedFiles =
std::unordered_set<std::wstring>();
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end(); it++)
if (!(*it)->isComplete()) usedFiles.insert((*it)->getSchematicName());
// Clean schematic files.
std::unordered_map<std::wstring, ConsoleSchematicFile*>* out =
new std::unordered_map<std::wstring, ConsoleSchematicFile*>();
for (auto it = usedFiles.begin(); it != usedFiles.end(); it++)
out->insert(std::pair<std::wstring, ConsoleSchematicFile*>(
*it, getSchematicFile(*it)));
return out;
}
void LevelGenerationOptions::loadBaseSaveData() {
int mountIndex = -1;
if (m_parentDLCPack != nullptr)
mountIndex = m_parentDLCPack->GetDLCMountIndex();
if (mountIndex > -1) {
if (StorageManager.MountInstalledDLC(
ProfileManager.GetPrimaryPad(), mountIndex,
&LevelGenerationOptions::packMounted, this,
"WPACK") != ERROR_IO_PENDING) {
// corrupt DLC
setLoadedData();
app.DebugPrintf("Failed to mount LGO DLC %d for pad %d\n",
mountIndex, ProfileManager.GetPrimaryPad());
} else {
m_bLoadingData = true;
app.DebugPrintf("Attempted to mount DLC data for LGO %d\n",
mountIndex);
}
} else {
setLoadedData();
app.SetAction(ProfileManager.GetPrimaryPad(),
eAppAction_ReloadTexturePack);
}
}
int LevelGenerationOptions::packMounted(void* pParam, int iPad, uint32_t dwErr,
uint32_t dwLicenceMask) {
LevelGenerationOptions* lgo = (LevelGenerationOptions*)pParam;
lgo->m_bLoadingData = false;
if (dwErr != ERROR_SUCCESS) {
// corrupt DLC
app.DebugPrintf("Failed to mount LGO DLC for pad %d: %d\n", iPad,
dwErr);
} else {
app.DebugPrintf("Mounted DLC for LGO, attempting to load data\n");
uint32_t dwFilesProcessed = 0;
int gameRulesCount = lgo->m_parentDLCPack->getDLCItemsCount(
DLCManager::e_DLCType_GameRulesHeader);
for (int i = 0; i < gameRulesCount; ++i) {
DLCGameRulesHeader* dlcFile =
(DLCGameRulesHeader*)lgo->m_parentDLCPack->getFile(
DLCManager::e_DLCType_GameRulesHeader, i);
if (!dlcFile->getGrfPath().empty()) {
File grf(app.getFilePath(lgo->m_parentDLCPack->GetPackID(),
dlcFile->getGrfPath(), true,
L"WPACK:"));
if (grf.exists()) {
std::filesystem::path grfPath = grf.getPath();
std::ifstream fileHandle(grfPath, std::ios::binary);
if (fileHandle) {
uint32_t dwFileSize = grf.length();
uint8_t* pbData = (uint8_t*)new uint8_t[dwFileSize];
fileHandle.read(
reinterpret_cast<char*>(pbData),
static_cast<std::streamsize>(dwFileSize));
if (!fileHandle) {
app.FatalLoadError();
}
// 4J-PB - is it possible that we can get here after a
// read fail and it's not an error?
dlcFile->setGrfData(pbData, dwFileSize,
lgo->m_stringTable);
delete[] pbData;
app.m_gameRules.setLevelGenerationOptions(dlcFile->lgo);
}
}
}
}
if (lgo->requiresBaseSave() && !lgo->getBaseSavePath().empty()) {
File save(app.getFilePath(lgo->m_parentDLCPack->GetPackID(),
lgo->getBaseSavePath(), true, L"WPACK:"));
if (save.exists()) {
std::filesystem::path savePath = save.getPath();
std::ifstream saveHandle(savePath, std::ios::binary);
if (saveHandle) {
auto dwFileSize = std::filesystem::file_size(savePath);
uint8_t* pbData = (uint8_t*)new uint8_t[dwFileSize];
saveHandle.read(reinterpret_cast<char*>(pbData),
static_cast<std::streamsize>(dwFileSize));
if (!saveHandle) {
app.FatalLoadError();
}
// 4J-PB - is it possible that we can get here after a read
// fail and it's not an error?
lgo->setBaseSaveData(pbData, dwFileSize);
}
}
}
uint32_t result = StorageManager.UnmountInstalledDLC("WPACK");
}
lgo->setLoadedData();
return 0;
}
void LevelGenerationOptions::reset_start() {
for (auto it = m_schematicRules.begin(); it != m_schematicRules.end();
it++) {
(*it)->reset();
}
}
void LevelGenerationOptions::reset_finish() {
// if (m_spawnPos) { delete m_spawnPos; m_spawnPos
// = nullptr; } if (m_stringTable) { delete m_stringTable;
// m_stringTable = nullptr; }
if (isFromDLC()) {
m_hasLoadedData = false;
}
}
GrSource* LevelGenerationOptions::info() { return m_pSrc; }
void LevelGenerationOptions::setSrc(eSrc src) { m_src = src; }
LevelGenerationOptions::eSrc LevelGenerationOptions::getSrc() { return m_src; }
bool LevelGenerationOptions::isTutorial() { return getSrc() == eSrc_tutorial; }
bool LevelGenerationOptions::isFromSave() { return getSrc() == eSrc_fromSave; }
bool LevelGenerationOptions::isFromDLC() { return getSrc() == eSrc_fromDLC; }
bool LevelGenerationOptions::requiresTexturePack() {
return info()->requiresTexturePack();
}
std::uint32_t LevelGenerationOptions::getRequiredTexturePackId() {
return info()->getRequiredTexturePackId();
}
std::wstring LevelGenerationOptions::getDefaultSaveName() {
switch (getSrc()) {
case eSrc_fromSave:
return getString(info()->getDefaultSaveName());
case eSrc_fromDLC:
return getString(info()->getDefaultSaveName());
case eSrc_tutorial:
return app.GetString(IDS_TUTORIALSAVENAME);
default:
break;
}
return L"";
}
const wchar_t* LevelGenerationOptions::getWorldName() {
switch (getSrc()) {
case eSrc_fromSave:
return getString(info()->getWorldName());
case eSrc_fromDLC:
return getString(info()->getWorldName());
case eSrc_tutorial:
return app.GetString(IDS_PLAY_TUTORIAL);
default:
break;
}
return L"";
}
const wchar_t* LevelGenerationOptions::getDisplayName() {
switch (getSrc()) {
case eSrc_fromSave:
return getString(info()->getDisplayName());
case eSrc_fromDLC:
return getString(info()->getDisplayName());
case eSrc_tutorial:
return L"";
default:
break;
}
return L"";
}
std::wstring LevelGenerationOptions::getGrfPath() {
return info()->getGrfPath();
}
bool LevelGenerationOptions::requiresBaseSave() {
return info()->requiresBaseSave();
}
std::wstring LevelGenerationOptions::getBaseSavePath() {
return info()->getBaseSavePath();
}
void LevelGenerationOptions::setGrSource(GrSource* grs) { m_pSrc = grs; }
void LevelGenerationOptions::setRequiresTexturePack(bool x) {
info()->setRequiresTexturePack(x);
}
void LevelGenerationOptions::setRequiredTexturePackId(std::uint32_t x) {
info()->setRequiredTexturePackId(x);
}
void LevelGenerationOptions::setDefaultSaveName(const std::wstring& x) {
info()->setDefaultSaveName(x);
}
void LevelGenerationOptions::setWorldName(const std::wstring& x) {
info()->setWorldName(x);
}
void LevelGenerationOptions::setDisplayName(const std::wstring& x) {
info()->setDisplayName(x);
}
void LevelGenerationOptions::setGrfPath(const std::wstring& x) {
info()->setGrfPath(x);
}
void LevelGenerationOptions::setBaseSavePath(const std::wstring& x) {
info()->setBaseSavePath(x);
}
bool LevelGenerationOptions::ready() { return info()->ready(); }
void LevelGenerationOptions::setBaseSaveData(std::uint8_t* pbData,
unsigned int dataSize) {
m_pbBaseSaveData = pbData;
m_baseSaveSize = dataSize;
}
std::uint8_t* LevelGenerationOptions::getBaseSaveData(unsigned int& size) {
size = m_baseSaveSize;
return m_pbBaseSaveData;
}
bool LevelGenerationOptions::hasBaseSaveData() {
return m_baseSaveSize > 0 && m_pbBaseSaveData != nullptr;
}
void LevelGenerationOptions::deleteBaseSaveData() {
delete[] m_pbBaseSaveData;
m_pbBaseSaveData = nullptr;
m_baseSaveSize = 0;
}
bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; }
void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; }
int64_t LevelGenerationOptions::getLevelSeed() { return m_seed; }
int LevelGenerationOptions::getLevelHasBeenInCreative() {
return m_bHasBeenInCreative;
}
Pos* LevelGenerationOptions::getSpawnPos() { return m_spawnPos; }
bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; }
bool LevelGenerationOptions::requiresGameRules() {
return m_bRequiresGameRules;
}
void LevelGenerationOptions::setRequiredGameRules(LevelRuleset* rules) {
m_requiredGameRules = rules;
m_bRequiresGameRules = true;
}
LevelRuleset* LevelGenerationOptions::getRequiredGameRules() {
return m_requiredGameRules;
}
@@ -0,0 +1,243 @@
#pragma once
// using namespace std;
// #pragma message("LevelGenerationOptions.h ")
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
#include "app/common/src/DLC/DLCPack.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/Localisation/StringTable.h"
#include "minecraft/world/level/levelgen/structure/StructureFeature.h"
class ApplySchematicRuleDefinition;
class LevelChunk;
class ConsoleGenerateStructure;
class ConsoleSchematicFile;
class LevelRuleset;
class BiomeOverride;
class StartFeature;
class DLCPack;
class Pos;
class StringTable;
class GrSource {
public:
// 4J-JEV:
// Moved all this here; I didn't like that all this header information
// was being mixed in with all the game information as they have
// completely different lifespans.
virtual ~GrSource() {}
virtual bool requiresTexturePack() = 0;
virtual std::uint32_t getRequiredTexturePackId() = 0;
virtual std::wstring getDefaultSaveName() = 0;
virtual const wchar_t* getWorldName() = 0;
virtual const wchar_t* getDisplayName() = 0;
virtual std::wstring getGrfPath() = 0;
virtual bool requiresBaseSave() = 0;
virtual std::wstring getBaseSavePath() = 0;
virtual void setRequiresTexturePack(bool) = 0;
virtual void setRequiredTexturePackId(std::uint32_t) = 0;
virtual void setDefaultSaveName(const std::wstring&) = 0;
virtual void setWorldName(const std::wstring&) = 0;
virtual void setDisplayName(const std::wstring&) = 0;
virtual void setGrfPath(const std::wstring&) = 0;
virtual void setBaseSavePath(const std::wstring&) = 0;
virtual bool ready() = 0;
// virtual void getGrfData(std::uint8_t *&pData, unsigned int &pSize)=0;
};
class JustGrSource : public GrSource {
protected:
std::wstring m_worldName;
std::wstring m_displayName;
std::wstring m_defaultSaveName;
bool m_bRequiresTexturePack;
std::uint32_t m_requiredTexturePackId;
std::wstring m_grfPath;
std::wstring m_baseSavePath;
bool m_bRequiresBaseSave;
public:
virtual bool requiresTexturePack();
virtual std::uint32_t getRequiredTexturePackId();
virtual std::wstring getDefaultSaveName();
virtual const wchar_t* getWorldName();
virtual const wchar_t* getDisplayName();
virtual std::wstring getGrfPath();
virtual bool requiresBaseSave();
virtual std::wstring getBaseSavePath();
virtual void setRequiresTexturePack(bool x);
virtual void setRequiredTexturePackId(std::uint32_t x);
virtual void setDefaultSaveName(const std::wstring& x);
virtual void setWorldName(const std::wstring& x);
virtual void setDisplayName(const std::wstring& x);
virtual void setGrfPath(const std::wstring& x);
virtual void setBaseSavePath(const std::wstring& x);
virtual bool ready();
JustGrSource();
};
class LevelGenerationOptions : public GameRuleDefinition {
public:
enum eSrc {
eSrc_none,
eSrc_fromSave, // Neither content or header is persistent.
eSrc_fromDLC, // Header is persistent, content should be deleted to
// conserve space.
eSrc_tutorial, // Both header and content is persistent, content cannot
// be reloaded.
eSrc_MAX
};
private:
eSrc m_src;
GrSource* m_pSrc;
GrSource* info();
bool m_hasLoadedData;
std::uint8_t* m_pbBaseSaveData;
unsigned int m_baseSaveSize;
public:
void setSrc(eSrc src);
eSrc getSrc();
bool isTutorial();
bool isFromSave();
bool isFromDLC();
bool requiresTexturePack();
std::uint32_t getRequiredTexturePackId();
std::wstring getDefaultSaveName();
const wchar_t* getWorldName();
const wchar_t* getDisplayName();
std::wstring getGrfPath();
bool requiresBaseSave();
std::wstring getBaseSavePath();
void setGrSource(GrSource* grs);
void setRequiresTexturePack(bool x);
void setRequiredTexturePackId(std::uint32_t x);
void setDefaultSaveName(const std::wstring& x);
void setWorldName(const std::wstring& x);
void setDisplayName(const std::wstring& x);
void setGrfPath(const std::wstring& x);
void setBaseSavePath(const std::wstring& x);
bool ready();
void setBaseSaveData(std::uint8_t* pbData, unsigned int dataSize);
std::uint8_t* getBaseSaveData(unsigned int& size);
bool hasBaseSaveData();
void deleteBaseSaveData();
bool hasLoadedData();
void setLoadedData();
private:
// This should match the "MapOptionsRule" definition in the XML schema
int64_t m_seed;
bool m_useFlatWorld;
Pos* m_spawnPos;
int m_bHasBeenInCreative;
std::vector<ApplySchematicRuleDefinition*> m_schematicRules;
std::vector<ConsoleGenerateStructure*> m_structureRules;
bool m_bHaveMinY;
int m_minY;
std::unordered_map<std::wstring, ConsoleSchematicFile*> m_schematics;
std::vector<BiomeOverride*> m_biomeOverrides;
std::vector<StartFeature*> m_features;
bool m_bRequiresGameRules;
LevelRuleset* m_requiredGameRules;
StringTable* m_stringTable;
DLCPack* m_parentDLCPack;
bool m_bLoadingData;
public:
LevelGenerationOptions(DLCPack* parentPack = nullptr);
~LevelGenerationOptions();
virtual ConsoleGameRules::EGameRuleType getActionType();
virtual void writeAttributes(DataOutputStream* dos,
unsigned int numAttributes);
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
int64_t getLevelSeed();
int getLevelHasBeenInCreative();
Pos* getSpawnPos();
bool getuseFlatWorld();
void processSchematics(LevelChunk* chunk);
void processSchematicsLighting(LevelChunk* chunk);
bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1);
private:
void clearSchematics();
public:
ConsoleSchematicFile* loadSchematicFile(const std::wstring& filename,
std::uint8_t* pbData,
unsigned int dataLength);
public:
ConsoleSchematicFile* getSchematicFile(const std::wstring& filename);
void releaseSchematicFile(const std::wstring& filename);
bool requiresGameRules();
void setRequiredGameRules(LevelRuleset* rules);
LevelRuleset* getRequiredGameRules();
void getBiomeOverride(int biomeId, std::uint8_t& tile,
std::uint8_t& topTile);
bool isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature,
int* orientation = nullptr);
void loadStringTable(StringTable* table);
const wchar_t* getString(const std::wstring& key);
std::unordered_map<std::wstring, ConsoleSchematicFile*>*
getUnfinishedSchematicFiles();
void loadBaseSaveData();
static int packMounted(void* pParam, int iPad, uint32_t dwErr,
uint32_t dwLicenceMask);
// 4J-JEV:
// ApplySchematicRules contain limited state
// which needs to be reset BEFORE a new game starts.
void reset_start();
// 4J-JEV:
// This file contains state that needs to be deleted
// or reset once a game has finished.
void reset_finish();
};
@@ -0,0 +1,21 @@
#include "LevelGenerators.h"
#include <algorithm>
#include "LevelGenerationOptions.h"
LevelGenerators::LevelGenerators() {}
void LevelGenerators::addLevelGenerator(const std::wstring& displayName,
LevelGenerationOptions* generator) {
if (!displayName.empty()) generator->setDisplayName(displayName);
m_levelGenerators.push_back(generator);
}
void LevelGenerators::removeLevelGenerator(LevelGenerationOptions* generator) {
std::vector<LevelGenerationOptions*>::iterator it;
while ((it = find(m_levelGenerators.begin(), m_levelGenerators.end(),
generator)) != m_levelGenerators.end()) {
m_levelGenerators.erase(it);
}
}
@@ -0,0 +1,24 @@
#pragma once
#include <format>
#include <string>
#include <vector>
// using namespace std;
class LevelGenerationOptions;
class LevelGenerators {
private:
std::vector<LevelGenerationOptions*> m_levelGenerators;
public:
LevelGenerators();
void addLevelGenerator(const std::wstring& displayName,
LevelGenerationOptions* generator);
void removeLevelGenerator(LevelGenerationOptions* generator);
std::vector<LevelGenerationOptions*>* getLevelGenerators() {
return &m_levelGenerators;
}
};
@@ -0,0 +1,60 @@
#include "StartFeature.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
StartFeature::StartFeature() {
m_chunkX = 0;
m_chunkZ = 0;
m_orientation = 0;
m_feature = StructureFeature::eFeature_Temples;
}
void StartFeature::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 4);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_chunkX);
dos->writeUTF(_toString(m_chunkX));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_chunkZ);
dos->writeUTF(_toString(m_chunkZ));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_feature);
dos->writeUTF(_toString((int)m_feature));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_orientation);
dos->writeUTF(_toString(m_orientation));
}
void StartFeature::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"chunkX") == 0) {
int value = _fromString<int>(attributeValue);
m_chunkX = value;
app.DebugPrintf("StartFeature: Adding parameter chunkX=%d\n", m_chunkX);
} else if (attributeName.compare(L"chunkZ") == 0) {
int value = _fromString<int>(attributeValue);
m_chunkZ = value;
app.DebugPrintf("StartFeature: Adding parameter chunkZ=%d\n", m_chunkZ);
} else if (attributeName.compare(L"orientation") == 0) {
int value = _fromString<int>(attributeValue);
m_orientation = value;
app.DebugPrintf("StartFeature: Adding parameter orientation=%d\n",
m_orientation);
} else if (attributeName.compare(L"feature") == 0) {
int value = _fromString<int>(attributeValue);
m_feature = (StructureFeature::EFeatureTypes)value;
app.DebugPrintf("StartFeature: Adding parameter feature=%d\n",
m_feature);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool StartFeature::isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature,
int* orientation) {
if (orientation != nullptr) *orientation = m_orientation;
return chunkX == m_chunkX && chunkZ == m_chunkZ && feature == m_feature;
}
@@ -0,0 +1,29 @@
#pragma once
// using namespace std;
#include <string>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "minecraft/world/level/levelgen/structure/StructureFeature.h"
class StartFeature : public GameRuleDefinition {
private:
int m_chunkX, m_chunkZ, m_orientation;
StructureFeature::EFeatureTypes m_feature;
public:
StartFeature();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_StartFeature;
}
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature,
int* orientation);
};
@@ -0,0 +1,102 @@
#include "XboxStructureActionGenerateBox.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
XboxStructureActionGenerateBox::XboxStructureActionGenerateBox() {
m_x0 = m_y0 = m_z0 = m_x1 = m_y1 = m_z1 = m_edgeTile = m_fillTile = 0;
m_skipAir = false;
}
void XboxStructureActionGenerateBox::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
ConsoleGenerateStructureAction::writeAttributes(dos, numAttrs + 9);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x0);
dos->writeUTF(_toString(m_x0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y0);
dos->writeUTF(_toString(m_y0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z0);
dos->writeUTF(_toString(m_z0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x1);
dos->writeUTF(_toString(m_x1));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y1);
dos->writeUTF(_toString(m_y1));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z1);
dos->writeUTF(_toString(m_z1));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_edgeTile);
dos->writeUTF(_toString(m_edgeTile));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_fillTile);
dos->writeUTF(_toString(m_fillTile));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_skipAir);
dos->writeUTF(_toString(m_skipAir));
}
void XboxStructureActionGenerateBox::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"x0") == 0) {
int value = _fromString<int>(attributeValue);
m_x0 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter x0=%d\n", m_x0);
} else if (attributeName.compare(L"y0") == 0) {
int value = _fromString<int>(attributeValue);
m_y0 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter y0=%d\n", m_y0);
} else if (attributeName.compare(L"z0") == 0) {
int value = _fromString<int>(attributeValue);
m_z0 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter z0=%d\n", m_z0);
} else if (attributeName.compare(L"x1") == 0) {
int value = _fromString<int>(attributeValue);
m_x1 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter x1=%d\n", m_x1);
} else if (attributeName.compare(L"y1") == 0) {
int value = _fromString<int>(attributeValue);
m_y1 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter y1=%d\n", m_y1);
} else if (attributeName.compare(L"z1") == 0) {
int value = _fromString<int>(attributeValue);
m_z1 = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter z1=%d\n", m_z1);
} else if (attributeName.compare(L"edgeTile") == 0) {
int value = _fromString<int>(attributeValue);
m_edgeTile = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter edgeTile=%d\n",
m_edgeTile);
} else if (attributeName.compare(L"fillTile") == 0) {
int value = _fromString<int>(attributeValue);
m_fillTile = value;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter fillTile=%d\n",
m_fillTile);
} else if (attributeName.compare(L"skipAir") == 0) {
if (attributeValue.compare(L"true") == 0) m_skipAir = true;
app.DebugPrintf(
"XboxStructureActionGenerateBox: Adding parameter skipAir=%s\n",
m_skipAir ? "true" : "false");
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool XboxStructureActionGenerateBox::generateBoxInLevel(
StructurePiece* structure, Level* level, BoundingBox* chunkBB) {
app.DebugPrintf("XboxStructureActionGenerateBox - generating a box\n");
structure->generateBox(level, chunkBB, m_x0, m_y0, m_z0, m_x1, m_y1, m_z1,
m_edgeTile, m_fillTile, m_skipAir);
return true;
}
@@ -0,0 +1,33 @@
#pragma once
#include <string>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
class StructurePiece;
class Level;
class BoundingBox;
class XboxStructureActionGenerateBox : public ConsoleGenerateStructureAction {
private:
int m_x0, m_y0, m_z0, m_x1, m_y1, m_z1, m_edgeTile, m_fillTile;
bool m_skipAir;
public:
XboxStructureActionGenerateBox();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_GenerateBox;
}
virtual int getEndX() { return m_x1; }
virtual int getEndY() { return m_y1; }
virtual int getEndZ() { return m_z1; }
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool generateBoxInLevel(StructurePiece* structure, Level* level,
BoundingBox* chunkBB);
};
@@ -0,0 +1,72 @@
#include "XboxStructureActionPlaceBlock.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
XboxStructureActionPlaceBlock::XboxStructureActionPlaceBlock() {
m_x = m_y = m_z = m_tile = m_data = 0;
}
void XboxStructureActionPlaceBlock::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
ConsoleGenerateStructureAction::writeAttributes(dos, numAttrs + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x);
dos->writeUTF(_toString(m_x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y);
dos->writeUTF(_toString(m_y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z);
dos->writeUTF(_toString(m_z));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_data);
dos->writeUTF(_toString(m_data));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_block);
dos->writeUTF(_toString(m_tile));
}
void XboxStructureActionPlaceBlock::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"x") == 0) {
int value = _fromString<int>(attributeValue);
m_x = value;
app.DebugPrintf(
"XboxStructureActionPlaceBlock: Adding parameter x=%d\n", m_x);
} else if (attributeName.compare(L"y") == 0) {
int value = _fromString<int>(attributeValue);
m_y = value;
app.DebugPrintf(
"XboxStructureActionPlaceBlock: Adding parameter y=%d\n", m_y);
} else if (attributeName.compare(L"z") == 0) {
int value = _fromString<int>(attributeValue);
m_z = value;
app.DebugPrintf(
"XboxStructureActionPlaceBlock: Adding parameter z=%d\n", m_z);
} else if (attributeName.compare(L"block") == 0) {
int value = _fromString<int>(attributeValue);
m_tile = value;
app.DebugPrintf(
"XboxStructureActionPlaceBlock: Adding parameter block=%d\n",
m_tile);
} else if (attributeName.compare(L"data") == 0) {
int value = _fromString<int>(attributeValue);
m_data = value;
app.DebugPrintf(
"XboxStructureActionPlaceBlock: Adding parameter data=%d\n",
m_data);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool XboxStructureActionPlaceBlock::placeBlockInLevel(StructurePiece* structure,
Level* level,
BoundingBox* chunkBB) {
app.DebugPrintf("XboxStructureActionPlaceBlock - placing a block\n");
structure->placeBlock(level, m_tile, m_data, m_x, m_y, m_z, chunkBB);
return true;
}
@@ -0,0 +1,32 @@
#pragma once
#include <string>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/ConsoleGenerateStructureAction.h"
class StructurePiece;
class Level;
class BoundingBox;
class XboxStructureActionPlaceBlock : public ConsoleGenerateStructureAction {
protected:
int m_x, m_y, m_z, m_tile, m_data;
public:
XboxStructureActionPlaceBlock();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_PlaceBlock;
}
virtual int getEndX() { return m_x; }
virtual int getEndY() { return m_y; }
virtual int getEndZ() { return m_z; }
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool placeBlockInLevel(StructurePiece* structure, Level* level,
BoundingBox* chunkBB);
};
@@ -0,0 +1,112 @@
#include "XboxStructureActionPlaceContainer.h"
#include <wchar.h>
#include <memory>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceBlock.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/AddItemRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "minecraft/world/Container.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/levelgen/structure/BoundingBox.h"
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
#include "minecraft/world/level/tile/Tile.h"
#include "minecraft/world/level/tile/entity/TileEntity.h"
XboxStructureActionPlaceContainer::XboxStructureActionPlaceContainer() {
m_tile = Tile::chest_Id;
}
XboxStructureActionPlaceContainer::~XboxStructureActionPlaceContainer() {
for (auto it = m_items.begin(); it != m_items.end(); ++it) {
delete *it;
}
}
// 4J-JEV: Super class handles attr-facing fine.
// void XboxStructureActionPlaceContainer::writeAttributes(DataOutputStream
// *dos, uint32_t numAttrs)
void XboxStructureActionPlaceContainer::getChildren(
std::vector<GameRuleDefinition*>* children) {
XboxStructureActionPlaceBlock::getChildren(children);
for (auto it = m_items.begin(); it != m_items.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* XboxStructureActionPlaceContainer::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_AddItem) {
rule = new AddItemRuleDefinition();
m_items.push_back((AddItemRuleDefinition*)rule);
} else {
#ifndef _CONTENT_PACKAGE
wprintf(
L"XboxStructureActionPlaceContainer: Attempted to add invalid "
L"child rule - %d\n",
ruleType);
#endif
}
return rule;
}
void XboxStructureActionPlaceContainer::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"facing") == 0) {
int value = _fromString<int>(attributeValue);
m_data = value;
app.DebugPrintf(
"XboxStructureActionPlaceContainer: Adding parameter facing=%d\n",
m_data);
} else {
XboxStructureActionPlaceBlock::addAttribute(attributeName,
attributeValue);
}
}
bool XboxStructureActionPlaceContainer::placeContainerInLevel(
StructurePiece* structure, Level* level, BoundingBox* chunkBB) {
int worldX = structure->getWorldX(m_x, m_z);
int worldY = structure->getWorldY(m_y);
int worldZ = structure->getWorldZ(m_x, m_z);
if (chunkBB->isInside(worldX, worldY, worldZ)) {
if (level->getTileEntity(worldX, worldY, worldZ) != nullptr) {
// Remove the current tile entity
level->removeTileEntity(worldX, worldY, worldZ);
level->setTileAndData(worldX, worldY, worldZ, 0, 0,
Tile::UPDATE_ALL);
}
level->setTileAndData(worldX, worldY, worldZ, m_tile, 0,
Tile::UPDATE_ALL);
std::shared_ptr<Container> container =
std::dynamic_pointer_cast<Container>(
level->getTileEntity(worldX, worldY, worldZ));
app.DebugPrintf(
"XboxStructureActionPlaceContainer - placing a container at "
"(%d,%d,%d)\n",
worldX, worldY, worldZ);
if (container != nullptr) {
level->setData(worldX, worldY, worldZ, m_data,
Tile::UPDATE_CLIENTS);
// Add items
int slotId = 0;
for (auto it = m_items.begin();
it != m_items.end() &&
(slotId < container->getContainerSize());
++it, ++slotId) {
AddItemRuleDefinition* addItem = *it;
addItem->addItemToContainer(container, slotId);
}
}
return true;
}
return false;
}
@@ -0,0 +1,39 @@
#pragma once
#include <string>
#include <vector>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "XboxStructureActionPlaceBlock.h"
class AddItemRuleDefinition;
class StructurePiece;
class Level;
class BoundingBox;
class XboxStructureActionPlaceContainer : public XboxStructureActionPlaceBlock {
private:
std::vector<AddItemRuleDefinition*> m_items;
public:
XboxStructureActionPlaceContainer();
~XboxStructureActionPlaceContainer();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_PlaceContainer;
}
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
// 4J-JEV: Super class handles attr-facing fine.
// virtual void writeAttributes(DataOutputStream *dos, uint32_t
// numAttributes);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool placeContainerInLevel(StructurePiece* structure, Level* level,
BoundingBox* chunkBB);
};
@@ -0,0 +1,78 @@
#include "XboxStructureActionPlaceSpawner.h"
#include <wchar.h>
#include <memory>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelGeneration/StructureActions/XboxStructureActionPlaceBlock.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/level/Level.h"
#include "minecraft/world/level/levelgen/structure/BoundingBox.h"
#include "minecraft/world/level/levelgen/structure/StructurePiece.h"
#include "minecraft/world/level/tile/Tile.h"
#include "minecraft/world/level/tile/entity/MobSpawnerTileEntity.h"
XboxStructureActionPlaceSpawner::XboxStructureActionPlaceSpawner() {
m_tile = Tile::mobSpawner_Id;
m_entityId = L"Pig";
}
XboxStructureActionPlaceSpawner::~XboxStructureActionPlaceSpawner() {}
void XboxStructureActionPlaceSpawner::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
XboxStructureActionPlaceBlock::writeAttributes(dos, numAttrs + 1);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_entity);
dos->writeUTF(m_entityId);
}
void XboxStructureActionPlaceSpawner::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"entity") == 0) {
m_entityId = attributeValue;
#ifndef _CONTENT_PACKAGE
wprintf(
L"XboxStructureActionPlaceSpawner: Adding parameter entity=%ls\n",
m_entityId.c_str());
#endif
} else {
XboxStructureActionPlaceBlock::addAttribute(attributeName,
attributeValue);
}
}
bool XboxStructureActionPlaceSpawner::placeSpawnerInLevel(
StructurePiece* structure, Level* level, BoundingBox* chunkBB) {
int worldX = structure->getWorldX(m_x, m_z);
int worldY = structure->getWorldY(m_y);
int worldZ = structure->getWorldZ(m_x, m_z);
if (chunkBB->isInside(worldX, worldY, worldZ)) {
if (level->getTileEntity(worldX, worldY, worldZ) != nullptr) {
// Remove the current tile entity
level->removeTileEntity(worldX, worldY, worldZ);
level->setTileAndData(worldX, worldY, worldZ, 0, 0,
Tile::UPDATE_ALL);
}
level->setTileAndData(worldX, worldY, worldZ, m_tile, 0,
Tile::UPDATE_ALL);
std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(worldX, worldY, worldZ));
#ifndef _CONTENT_PACKAGE
wprintf(
L"XboxStructureActionPlaceSpawner - placing a %ls spawner at "
L"(%d,%d,%d)\n",
m_entityId.c_str(), worldX, worldY, worldZ);
#endif
if (entity != nullptr) {
entity->setEntityId(m_entityId);
}
return true;
}
return false;
}
@@ -0,0 +1,31 @@
#pragma once
#include <string>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "XboxStructureActionPlaceBlock.h"
class StructurePiece;
class Level;
class BoundingBox;
class GRFObject;
class XboxStructureActionPlaceSpawner : public XboxStructureActionPlaceBlock {
private:
std::wstring m_entityId;
public:
XboxStructureActionPlaceSpawner();
~XboxStructureActionPlaceSpawner();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_PlaceSpawner;
}
virtual void writeAttributes(DataOutputStream* dos, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool placeSpawnerInLevel(StructurePiece* structure, Level* level,
BoundingBox* chunkBB);
};
@@ -0,0 +1,13 @@
#include "LevelRules.h"
LevelRules::LevelRules() {}
void LevelRules::addLevelRule(const std::wstring& displayName,
std::uint8_t* pbData, unsigned int dataLength) {}
void LevelRules::addLevelRule(const std::wstring& displayName,
LevelRuleset* rootRule) {}
void LevelRules::removeLevelRule(LevelRuleset* removing) {
// TODO ?
}
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <string>
class LevelRuleset;
class LevelRules {
public:
LevelRules();
void addLevelRule(const std::wstring& displayName, std::uint8_t* pbData,
unsigned int dataLength);
void addLevelRule(const std::wstring& displayName, LevelRuleset* rootRule);
void removeLevelRule(LevelRuleset* removing);
};
@@ -0,0 +1,78 @@
#include "AddEnchantmentRuleDefinition.h"
#include <algorithm>
#include <vector>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/item/EnchantedBookItem.h"
#include "minecraft/world/item/Item.h"
#include "minecraft/world/item/ItemInstance.h"
#include "minecraft/world/item/enchantment/Enchantment.h"
#include "minecraft/world/item/enchantment/EnchantmentCategory.h"
#include "minecraft/world/item/enchantment/EnchantmentInstance.h"
AddEnchantmentRuleDefinition::AddEnchantmentRuleDefinition() {
m_enchantmentId = m_enchantmentLevel = 0;
}
void AddEnchantmentRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
GameRuleDefinition::writeAttributes(dos, numAttributes + 2);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_enchantmentId);
dos->writeUTF(_toString(m_enchantmentId));
ConsoleGameRules::write(dos,
ConsoleGameRules::eGameRuleAttr_enchantmentLevel);
dos->writeUTF(_toString(m_enchantmentLevel));
}
void AddEnchantmentRuleDefinition::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"enchantmentId") == 0) {
int value = _fromString<int>(attributeValue);
if (value < 0) value = 0;
if (value >= 256) value = 255;
m_enchantmentId = value;
app.DebugPrintf(
"AddEnchantmentRuleDefinition: Adding parameter enchantmentId=%d\n",
m_enchantmentId);
} else if (attributeName.compare(L"enchantmentLevel") == 0) {
int value = _fromString<int>(attributeValue);
if (value < 0) value = 0;
m_enchantmentLevel = value;
app.DebugPrintf(
"AddEnchantmentRuleDefinition: Adding parameter "
"enchantmentLevel=%d\n",
m_enchantmentLevel);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool AddEnchantmentRuleDefinition::enchantItem(
std::shared_ptr<ItemInstance> item) {
bool enchanted = false;
if (item != nullptr) {
// 4J-JEV: Ripped code from enchantmenthelpers
// Maybe we want to add an addEnchantment method to EnchantmentHelpers
if (item->id == Item::enchantedBook_Id) {
Item::enchantedBook->addEnchantment(
item,
new EnchantmentInstance(m_enchantmentId, m_enchantmentLevel));
} else if (item->isEnchantable()) {
Enchantment* e = Enchantment::enchantments[m_enchantmentId];
if (e != nullptr && e->category->canEnchant(item->getItem())) {
int level = std::min(e->getMaxLevel(), m_enchantmentLevel);
item->enchant(e, m_enchantmentLevel);
enchanted = true;
}
}
}
return enchanted;
}
@@ -0,0 +1,29 @@
#pragma once
#include <memory>
#include <string>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
class ItemInstance;
class AddEnchantmentRuleDefinition : public GameRuleDefinition {
private:
int m_enchantmentId;
int m_enchantmentLevel;
public:
AddEnchantmentRuleDefinition();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_AddEnchantment;
}
virtual void writeAttributes(DataOutputStream*, unsigned int numAttrs);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool enchantItem(std::shared_ptr<ItemInstance> item);
};
@@ -0,0 +1,117 @@
#include "AddItemRuleDefinition.h"
#include <algorithm>
#include "AddEnchantmentRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/world/Container.h"
#include "minecraft/world/entity/player/Inventory.h"
#include "minecraft/world/item/Item.h"
#include "minecraft/world/item/ItemInstance.h"
AddItemRuleDefinition::AddItemRuleDefinition() {
m_itemId = m_quantity = m_auxValue = m_dataTag = 0;
m_slot = -1;
}
void AddItemRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_itemId);
dos->writeUTF(_toString(m_itemId));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_quantity);
dos->writeUTF(_toString(m_quantity));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_auxValue);
dos->writeUTF(_toString(m_auxValue));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_dataTag);
dos->writeUTF(_toString(m_dataTag));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_slot);
dos->writeUTF(_toString(m_slot));
}
void AddItemRuleDefinition::getChildren(
std::vector<GameRuleDefinition*>* children) {
GameRuleDefinition::getChildren(children);
for (auto it = m_enchantments.begin(); it != m_enchantments.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* AddItemRuleDefinition::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_AddEnchantment) {
rule = new AddEnchantmentRuleDefinition();
m_enchantments.push_back((AddEnchantmentRuleDefinition*)rule);
} else {
}
return rule;
}
void AddItemRuleDefinition::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"itemId") == 0) {
int value = _fromString<int>(attributeValue);
m_itemId = value;
// app.DebugPrintf(2,"AddItemRuleDefinition: Adding parameter
// itemId=%d\n",m_itemId);
} else if (attributeName.compare(L"quantity") == 0) {
int value = _fromString<int>(attributeValue);
m_quantity = value;
// app.DebugPrintf(2,"AddItemRuleDefinition: Adding parameter
// quantity=%d\n",m_quantity);
} else if (attributeName.compare(L"auxValue") == 0) {
int value = _fromString<int>(attributeValue);
m_auxValue = value;
// app.DebugPrintf(2,"AddItemRuleDefinition: Adding parameter
// auxValue=%d\n",m_auxValue);
} else if (attributeName.compare(L"dataTag") == 0) {
int value = _fromString<int>(attributeValue);
m_dataTag = value;
// app.DebugPrintf(2,"AddItemRuleDefinition: Adding parameter
// dataTag=%d\n",m_dataTag);
} else if (attributeName.compare(L"slot") == 0) {
int value = _fromString<int>(attributeValue);
m_slot = value;
// app.DebugPrintf(2,"AddItemRuleDefinition: Adding parameter
// slot=%d\n",m_slot);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool AddItemRuleDefinition::addItemToContainer(
std::shared_ptr<Container> container, int slotId) {
bool added = false;
if (Item::items[m_itemId] != nullptr) {
int quantity =
std::min(m_quantity, Item::items[m_itemId]->getMaxStackSize());
std::shared_ptr<ItemInstance> newItem = std::shared_ptr<ItemInstance>(
new ItemInstance(m_itemId, quantity, m_auxValue));
newItem->set4JData(m_dataTag);
for (auto it = m_enchantments.begin(); it != m_enchantments.end();
++it) {
(*it)->enchantItem(newItem);
}
if (m_slot >= 0 && m_slot < container->getContainerSize()) {
container->setItem(m_slot, newItem);
added = true;
} else if (slotId >= 0 && slotId < container->getContainerSize()) {
container->setItem(slotId, newItem);
added = true;
} else if (std::dynamic_pointer_cast<Inventory>(container) != nullptr) {
added =
std::dynamic_pointer_cast<Inventory>(container)->add(newItem);
}
}
return added;
}
@@ -0,0 +1,38 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
class Container;
class AddEnchantmentRuleDefinition;
class AddItemRuleDefinition : public GameRuleDefinition {
private:
int m_itemId;
int m_quantity;
int m_auxValue;
int m_dataTag;
int m_slot;
std::vector<AddEnchantmentRuleDefinition*> m_enchantments;
public:
AddItemRuleDefinition();
virtual void writeAttributes(DataOutputStream*, unsigned int numAttributes);
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_AddItem;
}
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
bool addItemToContainer(std::shared_ptr<Container> container, int slotId);
};
@@ -0,0 +1,121 @@
#include "CollectItemRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/network/Connection.h"
#include "minecraft/network/packet/UpdateGameRuleProgressPacket.h"
#include "minecraft/world/item/ItemInstance.h"
CollectItemRuleDefinition::CollectItemRuleDefinition() {
m_itemId = 0;
m_auxValue = 0;
m_quantity = 0;
}
CollectItemRuleDefinition::~CollectItemRuleDefinition() {}
void CollectItemRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
GameRuleDefinition::writeAttributes(dos, numAttributes + 3);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_itemId);
dos->writeUTF(_toString(m_itemId));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_auxValue);
dos->writeUTF(_toString(m_auxValue));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_quantity);
dos->writeUTF(_toString(m_quantity));
}
void CollectItemRuleDefinition::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"itemId") == 0) {
m_itemId = _fromString<int>(attributeValue);
app.DebugPrintf("CollectItemRule: Adding parameter itemId=%d\n",
m_itemId);
} else if (attributeName.compare(L"auxValue") == 0) {
m_auxValue = _fromString<int>(attributeValue);
app.DebugPrintf("CollectItemRule: Adding parameter m_auxValue=%d\n",
m_auxValue);
} else if (attributeName.compare(L"quantity") == 0) {
m_quantity = _fromString<int>(attributeValue);
app.DebugPrintf("CollectItemRule: Adding parameter m_quantity=%d\n",
m_quantity);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
int CollectItemRuleDefinition::getGoal() { return m_quantity; }
int CollectItemRuleDefinition::getProgress(GameRule* rule) {
GameRule::ValueType value = rule->getParameter(L"iQuantity");
return value.i;
}
void CollectItemRuleDefinition::populateGameRule(
GameRulesInstance::EGameRulesInstanceType type, GameRule* rule) {
GameRule::ValueType value;
value.i = 0;
rule->setParameter(L"iQuantity", value);
GameRuleDefinition::populateGameRule(type, rule);
}
bool CollectItemRuleDefinition::onCollectItem(
GameRule* rule, std::shared_ptr<ItemInstance> item) {
bool statusChanged = false;
if (item != nullptr && item->id == m_itemId &&
item->getAuxValue() == m_auxValue &&
item->get4JData() == m_4JDataValue) {
if (!getComplete(rule)) {
GameRule::ValueType value = rule->getParameter(L"iQuantity");
int quantityCollected = (value.i += item->count);
rule->setParameter(L"iQuantity", value);
statusChanged = true;
if (quantityCollected >= m_quantity) {
setComplete(rule, true);
app.DebugPrintf(
"Completed CollectItemRule with info - itemId:%d, "
"auxValue:%d, quantity:%d, dataTag:%d\n",
m_itemId, m_auxValue, m_quantity, m_4JDataValue);
if (rule->getConnection() != nullptr) {
rule->getConnection()->send(
std::shared_ptr<UpdateGameRuleProgressPacket>(
new UpdateGameRuleProgressPacket(
getActionType(), this->m_descriptionId,
m_itemId, m_auxValue, this->m_4JDataValue,
nullptr, 0)));
}
}
}
}
return statusChanged;
}
std::wstring CollectItemRuleDefinition::generateXml(
std::shared_ptr<ItemInstance> item) {
// 4J Stu - This should be kept in sync with the GameRulesDefinition.xsd
std::wstring xml = L"";
if (item != nullptr) {
xml = L"<CollectItemRule itemId=\"" + _toString<int>(item->id) +
L"\" quantity=\"SET\" descriptionName=\"OPTIONAL\" "
L"promptName=\"OPTIONAL\"";
if (item->getAuxValue() != 0)
xml +=
L" auxValue=\"" + _toString<int>(item->getAuxValue()) + L"\"";
if (item->get4JData() != 0)
xml += L" dataTag=\"" + _toString<int>(item->get4JData()) + L"\"";
xml += L"/>\n";
}
return xml;
}
@@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <string>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
class Pos;
class UseTileRuleDefinition;
class ItemInstance;
class CollectItemRuleDefinition : public GameRuleDefinition {
private:
// These values should map directly to the xsd definition for this Rule
int m_itemId;
unsigned char m_auxValue;
int m_quantity;
public:
CollectItemRuleDefinition();
~CollectItemRuleDefinition();
ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_CollectItemRule;
}
virtual void writeAttributes(DataOutputStream*, unsigned int numAttributes);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
virtual int getGoal();
virtual int getProgress(GameRule* rule);
virtual int getIcon() { return m_itemId; }
virtual int getAuxValue() { return m_auxValue; }
void populateGameRule(GameRulesInstance::EGameRulesInstanceType type,
GameRule* rule);
bool onCollectItem(GameRule* rule, std::shared_ptr<ItemInstance> item);
static std::wstring generateXml(std::shared_ptr<ItemInstance> item);
private:
// static std::wstring generateXml(CollectItemRuleDefinition *ruleDef);
};
@@ -0,0 +1,77 @@
#include "CompleteAllRuleDefinition.h"
#include <memory>
#include <unordered_map>
#include <utility>
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompoundGameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "minecraft/network/Connection.h"
#include "minecraft/network/packet/UpdateGameRuleProgressPacket.h"
void CompleteAllRuleDefinition::getChildren(
std::vector<GameRuleDefinition*>* children) {
CompoundGameRuleDefinition::getChildren(children);
}
bool CompleteAllRuleDefinition::onUseTile(GameRule* rule, int tileId, int x,
int y, int z) {
bool statusChanged =
CompoundGameRuleDefinition::onUseTile(rule, tileId, x, y, z);
if (statusChanged) updateStatus(rule);
return statusChanged;
}
bool CompleteAllRuleDefinition::onCollectItem(
GameRule* rule, std::shared_ptr<ItemInstance> item) {
bool statusChanged = CompoundGameRuleDefinition::onCollectItem(rule, item);
if (statusChanged) updateStatus(rule);
return statusChanged;
}
void CompleteAllRuleDefinition::updateStatus(GameRule* rule) {
int goal = 0;
int progress = 0;
for (auto it = rule->m_parameters.begin(); it != rule->m_parameters.end();
++it) {
if (it->second.isPointer) {
goal += it->second.gr->getGameRuleDefinition()->getGoal();
progress += it->second.gr->getGameRuleDefinition()->getProgress(
it->second.gr);
}
}
if (rule->getConnection() != nullptr) {
PacketData data;
data.goal = goal;
data.progress = progress;
int icon = -1;
int auxValue = 0;
if (m_lastRuleStatusChanged != nullptr) {
icon = m_lastRuleStatusChanged->getIcon();
auxValue = m_lastRuleStatusChanged->getAuxValue();
m_lastRuleStatusChanged = nullptr;
}
rule->getConnection()->send(
std::shared_ptr<UpdateGameRuleProgressPacket>(
new UpdateGameRuleProgressPacket(
getActionType(), this->m_descriptionId, icon, auxValue, 0,
&data, sizeof(PacketData))));
}
app.DebugPrintf("Updated CompleteAllRule - Completed %d of %d\n", progress,
goal);
}
std::wstring CompleteAllRuleDefinition::generateDescriptionString(
const std::wstring& description, void* data, int dataLength) {
PacketData* values = (PacketData*)data;
std::wstring newDesc = description;
newDesc =
replaceAll(newDesc, L"{*progress*}", _toString<int>(values->progress));
newDesc = replaceAll(newDesc, L"{*goal*}", _toString<int>(values->goal));
return newDesc;
}
@@ -0,0 +1,33 @@
#pragma once
#include <string>
#include "CompoundGameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
class GameRule;
class CompleteAllRuleDefinition : public CompoundGameRuleDefinition {
private:
typedef struct _packetData {
int goal;
int progress;
} PacketData;
public:
ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_CompleteAllRule;
}
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual bool onUseTile(GameRule* rule, int tileId, int x, int y, int z);
virtual bool onCollectItem(GameRule* rule,
std::shared_ptr<ItemInstance> item);
static std::wstring generateDescriptionString(
const std::wstring& description, void* data, int dataLength);
private:
void updateStatus(GameRule* rule);
};
@@ -0,0 +1,121 @@
#include "CompoundGameRuleDefinition.h"
#include <wchar.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CollectItemRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompleteAllRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/UpdatePlayerRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/UseTileRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
#include "console_helpers/StringHelpers.h"
CompoundGameRuleDefinition::CompoundGameRuleDefinition() {
m_lastRuleStatusChanged = nullptr;
}
CompoundGameRuleDefinition::~CompoundGameRuleDefinition() {
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
delete (*it);
}
}
void CompoundGameRuleDefinition::getChildren(
std::vector<GameRuleDefinition*>* children) {
GameRuleDefinition::getChildren(children);
for (auto it = m_children.begin(); it != m_children.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* CompoundGameRuleDefinition::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_CompleteAllRule) {
rule = new CompleteAllRuleDefinition();
} else if (ruleType == ConsoleGameRules::eGameRuleType_CollectItemRule) {
rule = new CollectItemRuleDefinition();
} else if (ruleType == ConsoleGameRules::eGameRuleType_UseTileRule) {
rule = new UseTileRuleDefinition();
} else if (ruleType == ConsoleGameRules::eGameRuleType_UpdatePlayerRule) {
rule = new UpdatePlayerRuleDefinition();
} else {
#ifndef _CONTENT_PACKAGE
wprintf(
L"CompoundGameRuleDefinition: Attempted to add invalid child rule "
L"- %d\n",
ruleType);
#endif
}
if (rule != nullptr) m_children.push_back(rule);
return rule;
}
void CompoundGameRuleDefinition::populateGameRule(
GameRulesInstance::EGameRulesInstanceType type, GameRule* rule) {
GameRule* newRule = nullptr;
int i = 0;
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
newRule = new GameRule(*it, rule->getConnection());
(*it)->populateGameRule(type, newRule);
GameRule::ValueType value;
value.gr = newRule;
value.isPointer = true;
// Somehow add the newRule to the current rule
rule->setParameter(L"rule" + _toString<int>(i), value);
++i;
}
GameRuleDefinition::populateGameRule(type, rule);
}
bool CompoundGameRuleDefinition::onUseTile(GameRule* rule, int tileId, int x,
int y, int z) {
bool statusChanged = false;
for (auto it = rule->m_parameters.begin(); it != rule->m_parameters.end();
++it) {
if (it->second.isPointer) {
bool changed = it->second.gr->getGameRuleDefinition()->onUseTile(
it->second.gr, tileId, x, y, z);
if (!statusChanged && changed) {
m_lastRuleStatusChanged =
it->second.gr->getGameRuleDefinition();
statusChanged = true;
}
}
}
return statusChanged;
}
bool CompoundGameRuleDefinition::onCollectItem(
GameRule* rule, std::shared_ptr<ItemInstance> item) {
bool statusChanged = false;
for (auto it = rule->m_parameters.begin(); it != rule->m_parameters.end();
++it) {
if (it->second.isPointer) {
bool changed =
it->second.gr->getGameRuleDefinition()->onCollectItem(
it->second.gr, item);
if (!statusChanged && changed) {
m_lastRuleStatusChanged =
it->second.gr->getGameRuleDefinition();
statusChanged = true;
}
}
}
return statusChanged;
}
void CompoundGameRuleDefinition::postProcessPlayer(
std::shared_ptr<Player> player) {
for (auto it = m_children.begin(); it != m_children.end(); ++it) {
(*it)->postProcessPlayer(player);
}
}
@@ -0,0 +1,31 @@
#pragma once
#include <vector>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
class CompoundGameRuleDefinition : public GameRuleDefinition {
protected:
std::vector<GameRuleDefinition*> m_children;
protected:
GameRuleDefinition* m_lastRuleStatusChanged;
public:
CompoundGameRuleDefinition();
virtual ~CompoundGameRuleDefinition();
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void populateGameRule(
GameRulesInstance::EGameRulesInstanceType type, GameRule* rule);
virtual bool onUseTile(GameRule* rule, int tileId, int x, int y, int z);
virtual bool onCollectItem(GameRule* rule,
std::shared_ptr<ItemInstance> item);
virtual void postProcessPlayer(std::shared_ptr<Player> player);
};
@@ -0,0 +1,167 @@
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include <assert.h>
#include <wchar.h>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompleteAllRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/LevelRuleset.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
class Connection;
GameRuleDefinition::GameRuleDefinition() {
m_descriptionId = L"";
m_promptId = L"";
m_4JDataValue = 0;
}
void GameRuleDefinition::write(DataOutputStream* dos) {
// Write EGameRuleType.
ConsoleGameRules::EGameRuleType eType = getActionType();
assert(eType != ConsoleGameRules::eGameRuleType_Invalid);
ConsoleGameRules::write(dos, eType); // stringID
writeAttributes(dos, 0);
// 4J-JEV: Get children.
std::vector<GameRuleDefinition*>* children =
new std::vector<GameRuleDefinition*>();
getChildren(children);
// Write children.
dos->writeInt(children->size());
for (auto it = children->begin(); it != children->end(); it++)
(*it)->write(dos);
}
void GameRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
dos->writeInt(numAttributes + 3);
ConsoleGameRules::write(dos,
ConsoleGameRules::eGameRuleAttr_descriptionName);
dos->writeUTF(m_descriptionId);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_promptName);
dos->writeUTF(m_promptId);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_dataTag);
dos->writeUTF(_toString(m_4JDataValue));
}
void GameRuleDefinition::getChildren(
std::vector<GameRuleDefinition*>* children) {}
GameRuleDefinition* GameRuleDefinition::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
#ifndef _CONTENT_PACKAGE
wprintf(L"GameRuleDefinition: Attempted to add invalid child rule - %d\n",
ruleType);
#endif
return nullptr;
}
void GameRuleDefinition::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"descriptionName") == 0) {
m_descriptionId = attributeValue;
#ifndef _CONTENT_PACKAGE
wprintf(L"GameRuleDefinition: Adding parameter descriptionId=%ls\n",
m_descriptionId.c_str());
#endif
} else if (attributeName.compare(L"promptName") == 0) {
m_promptId = attributeValue;
#ifndef _CONTENT_PACKAGE
wprintf(L"GameRuleDefinition: Adding parameter m_promptId=%ls\n",
m_promptId.c_str());
#endif
} else if (attributeName.compare(L"dataTag") == 0) {
m_4JDataValue = _fromString<int>(attributeValue);
app.DebugPrintf(
"GameRuleDefinition: Adding parameter m_4JDataValue=%d\n",
m_4JDataValue);
} else {
#ifndef _CONTENT_PACKAGE
wprintf(
L"GameRuleDefinition: Attempted to add invalid attribute: %ls\n",
attributeName.c_str());
#endif
}
}
void GameRuleDefinition::populateGameRule(
GameRulesInstance::EGameRulesInstanceType type, GameRule* rule) {
GameRule::ValueType value;
value.b = false;
rule->setParameter(L"bComplete", value);
}
bool GameRuleDefinition::getComplete(GameRule* rule) {
GameRule::ValueType value;
value = rule->getParameter(L"bComplete");
return value.b;
}
void GameRuleDefinition::setComplete(GameRule* rule, bool val) {
GameRule::ValueType value;
value = rule->getParameter(L"bComplete");
value.b = val;
rule->setParameter(L"bComplete", value);
}
std::vector<GameRuleDefinition*>* GameRuleDefinition::enumerate() {
// Get Vector.
std::vector<GameRuleDefinition*>* gRules;
gRules = new std::vector<GameRuleDefinition*>();
gRules->push_back(this);
getChildren(gRules);
return gRules;
}
std::unordered_map<GameRuleDefinition*, int>*
GameRuleDefinition::enumerateMap() {
std::unordered_map<GameRuleDefinition*, int>* out =
new std::unordered_map<GameRuleDefinition*, int>();
int i = 0;
std::vector<GameRuleDefinition*>* gRules = enumerate();
for (auto it = gRules->begin(); it != gRules->end(); it++)
out->insert(std::pair<GameRuleDefinition*, int>(*it, i++));
return out;
}
GameRulesInstance* GameRuleDefinition::generateNewGameRulesInstance(
GameRulesInstance::EGameRulesInstanceType type, LevelRuleset* rules,
Connection* connection) {
GameRulesInstance* manager = new GameRulesInstance(rules, connection);
rules->populateGameRule(type, manager);
return manager;
}
std::wstring GameRuleDefinition::generateDescriptionString(
ConsoleGameRules::EGameRuleType defType, const std::wstring& description,
void* data, int dataLength) {
std::wstring formatted = description;
switch (defType) {
case ConsoleGameRules::eGameRuleType_CompleteAllRule:
formatted = CompleteAllRuleDefinition::generateDescriptionString(
description, data, dataLength);
break;
default:
break;
};
return formatted;
}
@@ -0,0 +1,87 @@
#pragma once
// using namespace std;
#include <format>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/Rules/GameRulesInstance.h"
#include "minecraft/world/item/ItemInstance.h"
class GameRule;
class LevelRuleset;
class Player;
class WstringLookup;
class Connection;
class DataOutputStream;
class ItemInstance;
class GameRuleDefinition {
private:
// Owner type defines who this rule applies to
GameRulesInstance::EGameRulesInstanceType m_ownerType;
protected:
// These attributes should map to those in the XSD GameRuleType
std::wstring m_descriptionId;
std::wstring m_promptId;
int m_4JDataValue;
public:
GameRuleDefinition();
virtual ~GameRuleDefinition() {}
virtual ConsoleGameRules::EGameRuleType getActionType() = 0;
void setOwnerType(GameRulesInstance::EGameRulesInstanceType ownerType) {
m_ownerType = ownerType;
}
virtual void write(DataOutputStream*);
virtual void writeAttributes(DataOutputStream* dos,
unsigned int numAttributes);
virtual void getChildren(std::vector<GameRuleDefinition*>*);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
virtual void populateGameRule(
GameRulesInstance::EGameRulesInstanceType type, GameRule* rule);
bool getComplete(GameRule* rule);
void setComplete(GameRule* rule, bool val);
virtual int getGoal() { return 0; }
virtual int getProgress(GameRule* rule) { return 0; }
virtual int getIcon() { return -1; }
virtual int getAuxValue() { return 0; }
// Here we should have functions for all the hooks, with a GameRule* as the
// first parameter
virtual bool onUseTile(GameRule* rule, int tileId, int x, int y, int z) {
return false;
}
virtual bool onCollectItem(GameRule* rule,
std::shared_ptr<ItemInstance> item) {
return false;
}
virtual void postProcessPlayer(std::shared_ptr<Player> player) {}
std::vector<GameRuleDefinition*>* enumerate();
std::unordered_map<GameRuleDefinition*, int>* enumerateMap();
// Static functions
static GameRulesInstance* generateNewGameRulesInstance(
GameRulesInstance::EGameRulesInstanceType type, LevelRuleset* rules,
Connection* connection);
static std::wstring generateDescriptionString(
ConsoleGameRules::EGameRuleType defType,
const std::wstring& description, void* data = nullptr,
int dataLength = 0);
};
@@ -0,0 +1,57 @@
#include "LevelRuleset.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/CompoundGameRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/NamedAreaRuleDefinition.h"
#include "app/common/src/Localisation/StringTable.h"
class AABB;
LevelRuleset::LevelRuleset() { m_stringTable = nullptr; }
LevelRuleset::~LevelRuleset() {
for (auto it = m_areas.begin(); it != m_areas.end(); ++it) {
delete *it;
}
}
void LevelRuleset::getChildren(std::vector<GameRuleDefinition*>* children) {
CompoundGameRuleDefinition::getChildren(children);
for (auto it = m_areas.begin(); it != m_areas.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* LevelRuleset::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_NamedArea) {
rule = new NamedAreaRuleDefinition();
m_areas.push_back((NamedAreaRuleDefinition*)rule);
} else {
rule = CompoundGameRuleDefinition::addChild(ruleType);
}
return rule;
}
void LevelRuleset::loadStringTable(StringTable* table) {
m_stringTable = table;
}
const wchar_t* LevelRuleset::getString(const std::wstring& key) {
if (m_stringTable == nullptr) {
return L"";
} else {
return m_stringTable->getString(key);
}
}
AABB* LevelRuleset::getNamedArea(const std::wstring& areaName) {
AABB* area = nullptr;
for (auto it = m_areas.begin(); it != m_areas.end(); ++it) {
if ((*it)->getName().compare(areaName) == 0) {
area = (*it)->getArea();
break;
}
}
return area;
}
@@ -0,0 +1,36 @@
#pragma once
#include <string>
#include <vector>
#include "CompoundGameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
class NamedAreaRuleDefinition;
class AABB;
class StringTable;
class LevelRuleset : public CompoundGameRuleDefinition {
private:
std::vector<NamedAreaRuleDefinition*> m_areas;
StringTable* m_stringTable;
public:
LevelRuleset();
~LevelRuleset();
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_LevelRules;
}
void loadStringTable(StringTable* table);
const wchar_t* getString(const std::wstring& key);
AABB* getNamedArea(const std::wstring& areaName);
StringTable* getStringTable() { return m_stringTable; }
};
@@ -0,0 +1,75 @@
#include "NamedAreaRuleDefinition.h"
#include <wchar.h>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
NamedAreaRuleDefinition::NamedAreaRuleDefinition() {
m_name = L"";
m_area = AABB(0, 0, 0, 0, 0, 0);
}
void NamedAreaRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
GameRuleDefinition::writeAttributes(dos, numAttributes + 7);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_name);
dos->writeUTF(m_name);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x0);
dos->writeUTF(_toString(m_area.x0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y0);
dos->writeUTF(_toString(m_area.y0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z0);
dos->writeUTF(_toString(m_area.z0));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x1);
dos->writeUTF(_toString(m_area.x1));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y1);
dos->writeUTF(_toString(m_area.y1));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z1);
dos->writeUTF(_toString(m_area.z1));
}
void NamedAreaRuleDefinition::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"name") == 0) {
m_name = attributeValue;
#ifndef _CONTENT_PACKAGE
wprintf(L"NamedAreaRuleDefinition: Adding parameter name=%ls\n",
m_name.c_str());
#endif
} else if (attributeName.compare(L"x0") == 0) {
m_area.x0 = _fromString<int>(attributeValue);
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter x0=%f\n",
m_area.x0);
} else if (attributeName.compare(L"y0") == 0) {
m_area.y0 = _fromString<int>(attributeValue);
if (m_area.y0 < 0) m_area.y0 = 0;
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter y0=%f\n",
m_area.y0);
} else if (attributeName.compare(L"z0") == 0) {
m_area.z0 = _fromString<int>(attributeValue);
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter z0=%f\n",
m_area.z0);
} else if (attributeName.compare(L"x1") == 0) {
m_area.x1 = _fromString<int>(attributeValue);
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter x1=%f\n",
m_area.x1);
} else if (attributeName.compare(L"y1") == 0) {
m_area.y1 = _fromString<int>(attributeValue);
if (m_area.y1 < 0) m_area.y1 = 0;
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter y1=%f\n",
m_area.y1);
} else if (attributeName.compare(L"z1") == 0) {
m_area.z1 = _fromString<int>(attributeValue);
app.DebugPrintf("NamedAreaRuleDefinition: Adding parameter z1=%f\n",
m_area.z1);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
@@ -0,0 +1,29 @@
#pragma once
#include <string>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "minecraft/world/phys/AABB.h"
class NamedAreaRuleDefinition : public GameRuleDefinition {
private:
std::wstring m_name;
AABB m_area;
public:
NamedAreaRuleDefinition();
virtual void writeAttributes(DataOutputStream* dos,
unsigned int numAttributes);
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_NamedArea;
}
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
AABB* getArea() { return &m_area; }
std::wstring getName() { return m_name; }
};
@@ -0,0 +1,163 @@
#include "UpdatePlayerRuleDefinition.h"
#include <wchar.h>
#include <memory>
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/AddItemRuleDefinition.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "minecraft/Pos.h"
#include "minecraft/world/entity/player/Inventory.h"
#include "minecraft/world/entity/player/Player.h"
#include "minecraft/world/food/FoodData.h"
UpdatePlayerRuleDefinition::UpdatePlayerRuleDefinition() {
m_bUpdateHealth = m_bUpdateFood = m_bUpdateYRot = false;
;
m_health = 0;
m_food = 0;
m_spawnPos = nullptr;
m_yRot = 0.0f;
}
UpdatePlayerRuleDefinition::~UpdatePlayerRuleDefinition() {
for (auto it = m_items.begin(); it != m_items.end(); ++it) {
delete *it;
}
}
void UpdatePlayerRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
int attrCount = 3;
if (m_bUpdateHealth) ++attrCount;
if (m_bUpdateFood) ++attrCount;
if (m_bUpdateYRot) ++attrCount;
GameRuleDefinition::writeAttributes(dos, numAttributes + attrCount);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnX);
dos->writeUTF(_toString(m_spawnPos->x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnY);
dos->writeUTF(_toString(m_spawnPos->y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnZ);
dos->writeUTF(_toString(m_spawnPos->z));
if (m_bUpdateYRot) {
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_yRot);
dos->writeUTF(_toString(m_yRot));
}
if (m_bUpdateHealth) {
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_food);
dos->writeUTF(_toString(m_health));
}
if (m_bUpdateFood) {
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_health);
dos->writeUTF(_toString(m_food));
}
}
void UpdatePlayerRuleDefinition::getChildren(
std::vector<GameRuleDefinition*>* children) {
GameRuleDefinition::getChildren(children);
for (auto it = m_items.begin(); it != m_items.end(); it++)
children->push_back(*it);
}
GameRuleDefinition* UpdatePlayerRuleDefinition::addChild(
ConsoleGameRules::EGameRuleType ruleType) {
GameRuleDefinition* rule = nullptr;
if (ruleType == ConsoleGameRules::eGameRuleType_AddItem) {
rule = new AddItemRuleDefinition();
m_items.push_back((AddItemRuleDefinition*)rule);
} else {
#ifndef _CONTENT_PACKAGE
wprintf(
L"UpdatePlayerRuleDefinition: Attempted to add invalid child rule "
L"- %d\n",
ruleType);
#endif
}
return rule;
}
void UpdatePlayerRuleDefinition::addAttribute(
const std::wstring& attributeName, const std::wstring& attributeValue) {
if (attributeName.compare(L"spawnX") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->x = value;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter spawnX=%d\n", value);
} else if (attributeName.compare(L"spawnY") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->y = value;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter spawnY=%d\n", value);
} else if (attributeName.compare(L"spawnZ") == 0) {
if (m_spawnPos == nullptr) m_spawnPos = new Pos();
int value = _fromString<int>(attributeValue);
m_spawnPos->z = value;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter spawnZ=%d\n", value);
} else if (attributeName.compare(L"health") == 0) {
int value = _fromString<int>(attributeValue);
m_health = value;
m_bUpdateHealth = true;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter health=%d\n", value);
} else if (attributeName.compare(L"food") == 0) {
int value = _fromString<int>(attributeValue);
m_food = value;
m_bUpdateFood = true;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter health=%d\n", value);
} else if (attributeName.compare(L"yRot") == 0) {
float value = _fromString<float>(attributeValue);
m_yRot = value;
m_bUpdateYRot = true;
app.DebugPrintf(
"UpdatePlayerRuleDefinition: Adding parameter yRot=%f\n", value);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
void UpdatePlayerRuleDefinition::postProcessPlayer(
std::shared_ptr<Player> player) {
if (m_bUpdateHealth) {
player->lastHealth = m_health;
player->setHealth(m_health);
}
if (m_bUpdateFood) {
player->getFoodData()->setFoodLevel(m_food);
}
double x = player->x;
double y = player->y;
double z = player->z;
float yRot = player->yRot;
float xRot = player->xRot;
if (m_spawnPos != nullptr) {
x = m_spawnPos->x;
y = m_spawnPos->y;
z = m_spawnPos->z;
}
if (m_bUpdateYRot) {
yRot = m_yRot;
}
if (m_spawnPos != nullptr || m_bUpdateYRot)
player->absMoveTo(x, y, z, yRot, xRot);
for (auto it = m_items.begin(); it != m_items.end(); ++it) {
AddItemRuleDefinition* addItem = *it;
addItem->addItemToContainer(player->inventory, -1);
}
}
@@ -0,0 +1,41 @@
#pragma once
// using namespace std;
#include <string>
#include <vector>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
class AddItemRuleDefinition;
class Pos;
class UpdatePlayerRuleDefinition : public GameRuleDefinition {
private:
std::vector<AddItemRuleDefinition*> m_items;
bool m_bUpdateHealth, m_bUpdateFood, m_bUpdateYRot, m_bUpdateInventory;
int m_health;
int m_food;
Pos* m_spawnPos;
float m_yRot;
public:
UpdatePlayerRuleDefinition();
~UpdatePlayerRuleDefinition();
virtual ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_UpdatePlayerRule;
}
virtual void getChildren(std::vector<GameRuleDefinition*>* children);
virtual GameRuleDefinition* addChild(
ConsoleGameRules::EGameRuleType ruleType);
virtual void writeAttributes(DataOutputStream* dos,
unsigned int numAttributes);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
virtual void postProcessPlayer(std::shared_ptr<Player> player);
};
@@ -0,0 +1,80 @@
#include "UseTileRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Linux_App.h"
#include "console_helpers/StringHelpers.h"
#include "java/InputOutputStream/DataOutputStream.h"
UseTileRuleDefinition::UseTileRuleDefinition() {
m_tileId = -1;
m_useCoords = false;
}
void UseTileRuleDefinition::writeAttributes(DataOutputStream* dos,
unsigned int numAttributes) {
GameRuleDefinition::writeAttributes(dos, numAttributes + 5);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_tileId);
dos->writeUTF(_toString(m_tileId));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_useCoords);
dos->writeUTF(_toString(m_useCoords));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_x);
dos->writeUTF(_toString(m_coordinates.x));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_y);
dos->writeUTF(_toString(m_coordinates.y));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_z);
dos->writeUTF(_toString(m_coordinates.z));
}
void UseTileRuleDefinition::addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue) {
if (attributeName.compare(L"tileId") == 0) {
m_tileId = _fromString<int>(attributeValue);
app.DebugPrintf("UseTileRule: Adding parameter tileId=%d\n", m_tileId);
} else if (attributeName.compare(L"useCoords") == 0) {
m_useCoords = _fromString<bool>(attributeValue);
app.DebugPrintf("UseTileRule: Adding parameter useCoords=%s\n",
m_useCoords ? "true" : "false");
} else if (attributeName.compare(L"x") == 0) {
m_coordinates.x = _fromString<int>(attributeValue);
app.DebugPrintf("UseTileRule: Adding parameter x=%d\n",
m_coordinates.x);
} else if (attributeName.compare(L"y") == 0) {
m_coordinates.y = _fromString<int>(attributeValue);
app.DebugPrintf("UseTileRule: Adding parameter y=%d\n",
m_coordinates.y);
} else if (attributeName.compare(L"z") == 0) {
m_coordinates.z = _fromString<int>(attributeValue);
app.DebugPrintf("UseTileRule: Adding parameter z=%d\n",
m_coordinates.z);
} else {
GameRuleDefinition::addAttribute(attributeName, attributeValue);
}
}
bool UseTileRuleDefinition::onUseTile(GameRule* rule, int tileId, int x, int y,
int z) {
bool statusChanged = false;
if (m_tileId == tileId) {
if (!m_useCoords || (m_coordinates.x == x && m_coordinates.y == y &&
m_coordinates.z == z)) {
if (!getComplete(rule)) {
statusChanged = true;
setComplete(rule, true);
app.DebugPrintf(
"Completed UseTileRule with info - t:%d, coords:%s, x:%d, "
"y:%d, z:%d\n",
m_tileId, m_useCoords ? "true" : "false", m_coordinates.x,
m_coordinates.y, m_coordinates.z);
// Send a packet or some other announcement here
}
}
}
return statusChanged;
}
@@ -0,0 +1,30 @@
#pragma once
// using namespace std;
#include <string>
#include "GameRuleDefinition.h"
#include "app/common/src/GameRules/ConsoleGameRulesConstants.h"
#include "minecraft/Pos.h"
class UseTileRuleDefinition : public GameRuleDefinition {
private:
// These values should map directly to the xsd definition for this Rule
int m_tileId;
bool m_useCoords;
Pos m_coordinates;
public:
UseTileRuleDefinition();
ConsoleGameRules::EGameRuleType getActionType() {
return ConsoleGameRules::eGameRuleType_UseTileRule;
}
virtual void writeAttributes(DataOutputStream* dos,
unsigned int numAttributes);
virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue);
virtual bool onUseTile(GameRule* rule, int tileId, int x, int y, int z);
};
@@ -0,0 +1,98 @@
#include "app/common/src/GameRules/LevelRules/Rules/GameRule.h"
#include <wchar.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include "app/common/src/GameRules/LevelRules/RuleDefinitions/GameRuleDefinition.h"
#include "app/linux/Stubs/winapi_stubs.h"
#include "java/InputOutputStream/DataInputStream.h"
#include "java/InputOutputStream/DataOutputStream.h"
class Connection;
class ItemInstance;
GameRule::GameRule(GameRuleDefinition* definition, Connection* connection) {
m_definition = definition;
m_connection = connection;
}
GameRule::~GameRule() {
for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) {
if (it->second.isPointer) {
delete it->second.gr;
}
}
}
GameRule::ValueType GameRule::getParameter(const std::wstring& parameterName) {
if (m_parameters.find(parameterName) == m_parameters.end()) {
#ifndef _CONTENT_PACKAGE
wprintf(L"WARNING: Parameter %ls was not set before being fetched\n",
parameterName.c_str());
__debugbreak();
#endif
}
return m_parameters[parameterName];
}
void GameRule::setParameter(const std::wstring& parameterName,
ValueType value) {
if (m_parameters.find(parameterName) == m_parameters.end()) {
#ifndef _CONTENT_PACKAGE
wprintf(L"Adding parameter %ls to GameRule\n", parameterName.c_str());
#endif
} else {
#ifndef _CONTENT_PACKAGE
wprintf(L"Setting parameter %ls for GameRule\n", parameterName.c_str());
#endif
}
m_parameters[parameterName] = value;
}
GameRuleDefinition* GameRule::getGameRuleDefinition() { return m_definition; }
void GameRule::onUseTile(int tileId, int x, int y, int z) {
m_definition->onUseTile(this, tileId, x, y, z);
}
void GameRule::onCollectItem(std::shared_ptr<ItemInstance> item) {
m_definition->onCollectItem(this, item);
}
void GameRule::write(DataOutputStream* dos) {
// Find required parameters.
dos->writeInt(m_parameters.size());
for (auto it = m_parameters.begin(); it != m_parameters.end(); it++) {
std::wstring pName = (*it).first;
ValueType vType = (*it).second;
dos->writeUTF((*it).first);
dos->writeBoolean(vType.isPointer);
if (vType.isPointer)
vType.gr->write(dos);
else
dos->writeLong(vType.i64);
}
}
void GameRule::read(DataInputStream* dis) {
int savedParams = dis->readInt();
for (int i = 0; i < savedParams; i++) {
std::wstring pNames = dis->readUTF();
ValueType vType = getParameter(pNames);
if (dis->readBoolean()) {
vType.gr->read(dis);
} else {
vType.isPointer = false;
vType.i64 = dis->readLong();
setParameter(pNames, vType);
}
}
}
@@ -0,0 +1,68 @@
#pragma once
// using namespace std;
#include <stdint.h>
#include <memory>
#include <string>
#include <unordered_map>
class CompoundTag;
class GameRuleDefinition;
class Connection;
class DataInputStream;
class DataOutputStream;
class ItemInstance;
// A game rule maintains the state for one particular definition
class GameRule {
public:
typedef struct _ValueType {
union {
int64_t i64;
int i;
char c;
bool b;
float f;
double d;
GameRule* gr;
};
bool isPointer;
_ValueType() {
i64 = 0;
isPointer = false;
}
} ValueType;
private:
GameRuleDefinition* m_definition;
Connection* m_connection;
public:
typedef std::unordered_map<std::wstring, ValueType> stringValueMapType;
stringValueMapType m_parameters; // These are the members of this rule that
// maintain it's state
public:
GameRule(GameRuleDefinition* definition, Connection* connection = nullptr);
virtual ~GameRule();
Connection* getConnection() { return m_connection; }
ValueType getParameter(const std::wstring& parameterName);
void setParameter(const std::wstring& parameterName, ValueType value);
GameRuleDefinition* getGameRuleDefinition();
// All the hooks go here
void onUseTile(int tileId, int x, int y, int z);
void onCollectItem(std::shared_ptr<ItemInstance> item);
// 4J-JEV: For saving.
// CompoundTag *toTags(std::unordered_map<GameRuleDefinition *, int> *map);
// static GameRule *fromTags(Connection *c, CompoundTag *cTag,
// std::vector<GameRuleDefinition *> *grds);
void write(DataOutputStream* dos);
void read(DataInputStream* dos);
};
@@ -0,0 +1,25 @@
#pragma once
// using namespace std;
#include <vector>
#include "GameRule.h"
class GameRuleDefinition;
// The game rule manager belongs to a player/server or other object, and
// maintains their current state for each of the rules that apply to them
class GameRulesInstance : public GameRule {
public:
// These types are used by the GameRuleDefinition to know which rules to add
// to this GameRulesInstance
enum EGameRulesInstanceType {
eGameRulesInstanceType_ServerPlayer,
eGameRulesInstanceType_Server,
eGameRulesInstanceType_Count
};
public:
GameRulesInstance(GameRuleDefinition* definition, Connection* connection)
: GameRule(definition, connection) {}
// Functions for all the hooks should go here
};
@@ -0,0 +1,45 @@
#include "WstringLookup.h"
#include <utility>
WstringLookup::WstringLookup() { numIDs = 0; }
std::wstring WstringLookup::lookup(unsigned int id) {
// TODO
// if (id > currentMaxID)
// throw error
return int2str.at(id);
}
unsigned int WstringLookup::lookup(std::wstring str) {
if (str2int.find(str) == str2int.end()) {
std::pair<std::wstring, unsigned int> p =
std::pair<std::wstring, unsigned int>(str, numIDs);
str2int.insert(p);
int2str.push_back(str);
return numIDs++;
} else {
return str2int.at(str);
}
}
void WstringLookup::getTable(std::wstring** lookup, unsigned int* len) {
// Outputs
std::wstring* out_lookup;
unsigned int out_len;
// Fill lookup.
out_lookup = new std::wstring[int2str.size()];
for (unsigned int i = 0; i < numIDs; i++) out_lookup[i] = int2str.at(i);
out_len = numIDs;
// Return.
*lookup = out_lookup;
*len = out_len;
return;
}
@@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <unordered_map>
#include <vector>
class WstringLookup {
private:
unsigned int numIDs;
std::unordered_map<std::wstring, unsigned int> str2int;
std::vector<std::wstring> int2str;
public:
WstringLookup();
std::wstring lookup(unsigned int id);
unsigned int lookup(std::wstring);
void getTable(std::wstring** lookup, unsigned int* len);
};
@@ -0,0 +1,100 @@
#include "LeaderboardInterface.h"
#include <assert.h>
#include "app/common/src/Leaderboards/LeaderboardManager.h"
LeaderboardInterface::LeaderboardInterface(IPlatformLeaderboard* man) {
m_manager = man;
m_pending = false;
m_filter = (IPlatformLeaderboard::EFilterMode)-1;
m_callback = nullptr;
m_difficulty = 0;
m_type = IPlatformLeaderboard::eStatsType_UNDEFINED;
m_startIndex = 0;
m_readCount = 0;
m_manager->OpenSession();
}
LeaderboardInterface::~LeaderboardInterface() {
m_manager->CancelOperation();
m_manager->CloseSession();
}
void LeaderboardInterface::ReadStats_Friends(
LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type, PlayerUID myUID,
unsigned int startIndex, unsigned int readCount) {
m_filter = IPlatformLeaderboard::eFM_Friends;
m_pending = true;
m_callback = callback;
m_difficulty = difficulty;
m_type = type;
m_myUID = myUID;
m_startIndex = startIndex;
m_readCount = readCount;
tick();
}
void LeaderboardInterface::ReadStats_MyScore(
LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type, PlayerUID myUID,
unsigned int readCount) {
m_filter = IPlatformLeaderboard::eFM_MyScore;
m_pending = true;
m_callback = callback;
m_difficulty = difficulty;
m_type = type;
m_myUID = myUID;
m_readCount = readCount;
tick();
}
void LeaderboardInterface::ReadStats_TopRank(
LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type, unsigned int startIndex,
unsigned int readCount) {
m_filter = IPlatformLeaderboard::eFM_TopRank;
m_pending = true;
m_callback = callback;
m_difficulty = difficulty;
m_type = type;
m_startIndex = startIndex;
m_readCount = readCount;
tick();
}
void LeaderboardInterface::CancelOperation() {
m_manager->CancelOperation();
m_pending = false;
}
void LeaderboardInterface::tick() {
if (m_pending) m_pending = !callManager();
}
bool LeaderboardInterface::callManager() {
switch (m_filter) {
case IPlatformLeaderboard::eFM_Friends:
return m_manager->ReadStats_Friends(m_callback, m_difficulty,
m_type, m_myUID, m_startIndex,
m_readCount);
case IPlatformLeaderboard::eFM_MyScore:
return m_manager->ReadStats_MyScore(m_callback, m_difficulty,
m_type, m_myUID, m_readCount);
case IPlatformLeaderboard::eFM_TopRank:
return m_manager->ReadStats_TopRank(
m_callback, m_difficulty, m_type, m_startIndex, m_readCount);
default:
assert(false);
return true;
}
}
@@ -0,0 +1,41 @@
#pragma once
#include "4J.Common/4J_Compat.h"
#include "LeaderboardManager.h"
// 4J-JEV: Simple interface for handling ReadStat failures.
class LeaderboardInterface {
private:
IPlatformLeaderboard* m_manager;
bool m_pending;
// Arguments.
IPlatformLeaderboard::EFilterMode m_filter;
LeaderboardReadListener* m_callback;
int m_difficulty;
IPlatformLeaderboard::EStatsType m_type;
PlayerUID m_myUID;
unsigned int m_startIndex;
unsigned int m_readCount;
public:
LeaderboardInterface(IPlatformLeaderboard* man);
~LeaderboardInterface();
void ReadStats_Friends(LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type, PlayerUID myUID,
unsigned int startIndex, unsigned int readCount);
void ReadStats_MyScore(LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type, PlayerUID myUID,
unsigned int readCount);
void ReadStats_TopRank(LeaderboardReadListener* callback, int difficulty,
IPlatformLeaderboard::EStatsType type,
unsigned int startIndex, unsigned int readCount);
void CancelOperation();
void tick();
private:
bool callManager();
};

Some files were not shown because too many files have changed in this diff Show More