WIP on redesigning how asset checking/downloading works in the launcher

This commit is contained in:
UnknownShadow200 2023-06-14 21:49:41 +10:00
parent 9f951893a1
commit 946fb1f773
7 changed files with 166 additions and 87 deletions

View File

@ -50,7 +50,7 @@ int Game_FpsLimit, Game_Vertices;
cc_bool Game_SimpleArmsAnim;
cc_bool Game_ClassicMode, Game_ClassicHacks;
cc_bool Game_AllowCustomBlocks, Game_UseCPE;
cc_bool Game_AllowCustomBlocks;
cc_bool Game_AllowServerTextures;
cc_bool Game_ViewBobbing, Game_HideGui, Game_DefaultZipMissing;
@ -304,7 +304,6 @@ static void LoadOptions(void) {
Game_ClassicMode = Options_GetBool(OPT_CLASSIC_MODE, false);
Game_ClassicHacks = Options_GetBool(OPT_CLASSIC_HACKS, false);
Game_AllowCustomBlocks = Options_GetBool(OPT_CUSTOM_BLOCKS, true);
Game_UseCPE = !Game_ClassicMode && Options_GetBool(OPT_CPE, true);
Game_SimpleArmsAnim = Options_GetBool(OPT_SIMPLE_ARMS_ANIM, false);
Game_ViewBobbing = Options_GetBool(OPT_VIEW_BOBBING, true);

View File

@ -38,7 +38,6 @@ extern cc_bool Game_ClassicMode;
extern cc_bool Game_ClassicHacks;
#define Game_PureClassic (Game_ClassicMode && !Game_ClassicHacks)
extern cc_bool Game_AllowCustomBlocks;
extern cc_bool Game_UseCPE;
extern cc_bool Game_AllowServerTextures;
extern cc_bool Game_ViewBobbing;
@ -53,6 +52,7 @@ enum GAME_VERSION_ {
};
struct GameVersion {
const char* Name;
cc_bool HasCPE;
cc_uint8 Version, Protocol, MaxCoreBlock;
cc_uint8 BlocksPerRow, InventorySize;
const cc_uint8* Inventory;

View File

@ -40,36 +40,37 @@ static const cc_uint8 v4_hotbar[INVENTORY_BLOCKS_PER_HOTBAR] = {
};
static const struct GameVersion version_cpe = {
"0.30", VERSION_CPE,
"0.30", true, VERSION_CPE,
PROTOCOL_0030, BLOCK_MAX_CPE,
10, sizeof(v7_inventory), NULL, v7_hotbar
};
static const struct GameVersion version_0030 = {
"0.30", VERSION_0030,
"0.30", false, VERSION_0030,
PROTOCOL_0030, BLOCK_OBSIDIAN,
9, sizeof(v7_inventory), v7_inventory, v7_hotbar
};
static const struct GameVersion version_0023 = {
"0.0.23a", VERSION_0023,
"0.0.23a", false, VERSION_0023,
PROTOCOL_0020, BLOCK_GOLD,
8, sizeof(v6_inventory), v6_inventory, v6_hotbar
};
static const struct GameVersion version_0019 = {
"0.0.19a", VERSION_0019,
"0.0.19a", false, VERSION_0019,
PROTOCOL_0019, BLOCK_GLASS,
6, sizeof(v5_inventory), v5_inventory, v5_hotbar
};
static const struct GameVersion version_0017 = {
"0.0.17a", VERSION_0017,
"0.0.17a", false, VERSION_0017,
PROTOCOL_0017, BLOCK_LEAVES,
6, sizeof(v4_inventory), v4_inventory, v4_hotbar
};
void GameVersion_Load(void) {
cc_bool hasCPE = !Game_ClassicMode && Options_GetBool(OPT_CPE, true);
int version = Options_GetInt(OPT_GAME_VERSION, VERSION_0017, VERSION_0030, VERSION_0030);
const struct GameVersion* ver = &version_cpe;
if (Game_UseCPE) {
if (hasCPE) {
/* defaults to CPE already */
} else if (version == VERSION_0030) {
ver = &version_0030;

View File

@ -3233,7 +3233,7 @@ void NostalgiaAppearanceScreen_Show(void) {
*----------------------------------------------NostalgiaFunctionalityScreen-----------------------------------------------*
*#########################################################################################################################*/
static void NostalgiaScreen_UpdateVersionDisabled(void) {
MenuOptionsScreen_Instance.buttons[3].disabled = Game_UseCPE;
MenuOptionsScreen_Instance.buttons[3].disabled = Game_Version.HasCPE;
}
static void NostalgiaScreen_GetTexs(cc_string* v) { Menu_GetBool(v, Game_AllowServerTextures); }
@ -3242,9 +3242,10 @@ static void NostalgiaScreen_SetTexs(const cc_string* v) { Game_AllowServerTextur
static void NostalgiaScreen_GetCustom(cc_string* v) { Menu_GetBool(v, Game_AllowCustomBlocks); }
static void NostalgiaScreen_SetCustom(const cc_string* v) { Game_AllowCustomBlocks = Menu_SetBool(v, OPT_CUSTOM_BLOCKS); }
static void NostalgiaScreen_GetCPE(cc_string* v) { Menu_GetBool(v, Game_UseCPE); }
static void NostalgiaScreen_GetCPE(cc_string* v) { Menu_GetBool(v, Game_Version.HasCPE); }
static void NostalgiaScreen_SetCPE(const cc_string* v) {
Game_UseCPE = Menu_SetBool(v, OPT_CPE);
Menu_SetBool(v, OPT_CPE);
GameVersion_Load();
NostalgiaScreen_UpdateVersionDisabled();
}

View File

@ -386,7 +386,7 @@ void Classic_SendLogin(void) {
/* and will get stuck waiting for data if client connects using version 5 and only sends 130 bytes */
/* To workaround this, include a 'ping packet' after 'version 5 handshake packet' - version 5 server software */
/* will do nothing with the ping packet, and the aforementioned server software will be happy with 131 bytes */
data[130] = Game_UseCPE ? 0x42 : (Game_Version.Protocol <= PROTOCOL_0019 ? OPCODE_PING : 0x00);
data[130] = Game_Version.HasCPE ? 0x42 : (Game_Version.Protocol <= PROTOCOL_0019 ? OPCODE_PING : 0x00);
}
Server.SendData(data, 131);
}
@ -1588,7 +1588,7 @@ static void CPE_Reset(void) {
cpe_needD3Fix = false; cpe_extEntityPos = false; cpe_twoWayPing = false;
cpe_pluginMessages = false; cpe_extTextures = false; cpe_fastMap = false;
cpe_extBlocks = false; Game_UseCPEBlocks = false; cpe_blockPerms = false;
if (!Game_UseCPE) return;
if (!Game_Version.HasCPE) return;
Net_Set(OPCODE_EXT_INFO, CPE_ExtInfo, 67);
Net_Set(OPCODE_EXT_ENTRY, CPE_ExtEntry, 69);
@ -1760,7 +1760,7 @@ static void BlockDefs_DefineBlockExt(cc_uint8* data) {
}
static void BlockDefs_Reset(void) {
if (!Game_UseCPE || !Game_AllowCustomBlocks) return;
if (!Game_Version.HasCPE || !Game_AllowCustomBlocks) return;
Net_Set(OPCODE_DEFINE_BLOCK, BlockDefs_DefineBlock, 80);
Net_Set(OPCODE_UNDEFINE_BLOCK, BlockDefs_UndefineBlock, 2);
Net_Set(OPCODE_DEFINE_BLOCK_EXT, BlockDefs_DefineBlockExt, 85);

View File

@ -13,6 +13,18 @@
#include "Logger.h"
#include "LWeb.h"
#include "Http.h"
/* Represents a set of assets/resources */
/* E.g. music set, sounds set, textures set */
struct AssetSet {
/* Checks whether all assets in this asset set exist on disc */
void (*CheckExistence)(void);
/* Begins asynchronously downloading the missing assets in this asset set */
void (*DownloadAssets)(void);
/* Checks if any assets have been downloaded, and processes them if so */
void (*CheckStatus)(void);
};
int Resources_Count, Resources_Size;
union ResourceValue {
@ -31,17 +43,19 @@ struct ResourceZipEntry {
#define RESOURCE_TYPE_PNG 2
#define RESOURCE_TYPE_CONST 3
static CC_NOINLINE cc_bool Fetcher_Get(int reqID, struct HttpRequest* item);
/*########################################################################################################################*
*--------------------------------------------------------Music resources--------------------------------------------------*
*---------------------------------------------------------Music assets----------------------------------------------------*
*#########################################################################################################################*/
static struct MusicResource {
static struct MusicAsset {
const char* name;
const char* hash;
short size;
cc_bool downloaded;
int reqID;
} musicResources[] = {
} musicAssets[] = {
{ "calm1.ogg", "50a59a4f56e4046701b758ddbb1c1587efa4cadf", 2472 },
{ "calm2.ogg", "74da65c99aa578486efa7b69983d3533e14c0d6e", 1931 },
{ "calm3.ogg", "14ae57a6bce3d4254daa8be2b098c2d99743cc3f", 2181 },
@ -51,25 +65,51 @@ static struct MusicResource {
{ "hal4.ogg", "5e7d63e75c6e042f452bc5e151276911ef92fed8", 2499 }
};
static void MusicResources_CheckExistence(void) {
static void MusicAssets_CheckExistence(void) {
cc_string path; char pathBuffer[FILENAME_SIZE];
int i;
String_InitArray(path, pathBuffer);
for (i = 0; i < Array_Elems(musicResources); i++) {
for (i = 0; i < Array_Elems(musicAssets); i++)
{
path.length = 0;
String_Format1(&path, "audio/%c", musicResources[i].name);
String_Format1(&path, "audio/%c", musicAssets[i].name);
musicResources[i].downloaded = File_Exists(&path);
if (musicResources[i].downloaded) continue;
musicAssets[i].downloaded = File_Exists(&path);
if (musicAssets[i].downloaded) continue;
Resources_Size += musicResources[i].size;
Resources_Size += musicAssets[i].size;
Resources_Count++;
}
}
static void MusicResource_Save(const char* name, struct HttpRequest* req) {
/*########################################################################################################################*
*-----------------------------------------------------Music asset fetching -----------------------------------------------*
*#########################################################################################################################*/
CC_NOINLINE static int MusicAsset_Download(const char* hash) {
cc_string url; char urlBuffer[URL_MAX_SIZE];
String_InitArray(url, urlBuffer);
String_Format3(&url, "https://resources.download.minecraft.net/%r%r/%c",
&hash[0], &hash[1], hash);
return Http_AsyncGetData(&url, 0);
}
static void MusicAssets_DownloadResources(void) {
int i;
for (i = 0; i < Array_Elems(musicAssets); i++)
{
if (musicAssets[i].downloaded) continue;
musicAssets[i].reqID = MusicAsset_Download(musicAssets[i].hash);
}
}
/*########################################################################################################################*
*----------------------------------------------------Music asset processing ----------------------------------------------*
*#########################################################################################################################*/
static void MusicAsset_Save(const char* name, struct HttpRequest* req) {
cc_string path; char pathBuffer[STRING_SIZE];
cc_result res;
@ -80,24 +120,39 @@ static void MusicResource_Save(const char* name, struct HttpRequest* req) {
if (res) Logger_SysWarn(res, "saving music file");
}
CC_NOINLINE static int MusicResource_Download(const char* hash) {
cc_string url; char urlBuffer[URL_MAX_SIZE];
static void MusicAsset_Check(struct MusicAsset* music) {
struct HttpRequest item;
if (!Fetcher_Get(music->reqID, &item)) return;
String_InitArray(url, urlBuffer);
String_Format3(&url, "https://resources.download.minecraft.net/%r%r/%c",
&hash[0], &hash[1], hash);
return Http_AsyncGetData(&url, 0);
music->downloaded = true;
MusicAsset_Save(music->name, &item);
HttpRequest_Free(&item);
}
static void MusicAssets_CheckStatus(void) {
int i;
for (i = 0; i < Array_Elems(musicAssets); i++)
{
if (musicAssets[i].downloaded) continue;
MusicAsset_Check(&musicAssets[i]);
}
}
static const struct AssetSet musicAssetSet = {
MusicAssets_CheckExistence,
MusicAssets_DownloadResources,
MusicAssets_CheckStatus
};
/*########################################################################################################################*
*--------------------------------------------------------Sound resources--------------------------------------------------*
*---------------------------------------------------------Sound assets----------------------------------------------------*
*#########################################################################################################################*/
static struct SoundResource {
static struct SoundAsset {
const char* name;
const char* hash;
int reqID;
} soundResources[] = {
} soundAssets[] = {
{ "dig_cloth1", "5fd568d724ba7d53911b6cccf5636f859d2662e8" }, { "dig_cloth2", "56c1d0ac0de2265018b2c41cb571cc6631101484" },
{ "dig_cloth3", "9c63f2a3681832dc32d206f6830360bfe94b5bfc" }, { "dig_cloth4", "55da1856e77cfd31a7e8c3d358e1f856c5583198" },
{ "dig_grass1", "41cbf5dd08e951ad65883854e74d2e034929f572" }, { "dig_grass2", "86cb1bb0c45625b18e00a64098cd425a38f6d3f2" },
@ -132,26 +187,44 @@ static struct SoundResource {
};
static cc_bool allSoundsExist;
static void SoundResources_CheckExistence(void) {
static void SoundAssets_CheckExistence(void) {
cc_string path; char pathBuffer[FILENAME_SIZE];
int i;
String_InitArray(path, pathBuffer);
for (i = 0; i < Array_Elems(soundResources); i++) {
for (i = 0; i < Array_Elems(soundAssets); i++)
{
path.length = 0;
String_Format1(&path, "audio/%c.wav", soundResources[i].name);
String_Format1(&path, "audio/%c.wav", soundAssets[i].name);
if (File_Exists(&path)) continue;
allSoundsExist = false;
Resources_Count += Array_Elems(soundResources);
Resources_Count += Array_Elems(soundAssets);
Resources_Size += 417;
return;
}
allSoundsExist = true;
}
/*########################################################################################################################*
*-----------------------------------------------------Sound asset fetching -----------------------------------------------*
*#########################################################################################################################*/
#define SoundAsset_Download(hash) MusicAsset_Download(hash)
static void SoundAssets_DownloadAssets(void) {
int i;
for (i = 0; i < Array_Elems(soundAssets); i++)
{
if (allSoundsExist) continue;
soundAssets[i].reqID = SoundAsset_Download(soundAssets[i].hash);
}
}
/*########################################################################################################################*
*----------------------------------------------------Sound asset processing ----------------------------------------------*
*#########################################################################################################################*/
#define WAV_FourCC(a, b, c, d) (((cc_uint32)a << 24) | ((cc_uint32)b << 16) | ((cc_uint32)c << 8) | (cc_uint32)d)
#define WAV_HDR_SIZE 44
@ -238,7 +311,28 @@ static void SoundPatcher_Save(const char* name, struct HttpRequest* req) {
Vorbis_Free(&ctx);
}
#define SoundResource_Download(hash) MusicResource_Download(hash)
static void SoundAsset_Check(const struct SoundAsset* sound) {
struct HttpRequest item;
if (!Fetcher_Get(sound->reqID, &item)) return;
SoundPatcher_Save(sound->name, &item);
HttpRequest_Free(&item);
}
static void SoundAssets_CheckStatus(void) {
int i;
for (i = 0; i < Array_Elems(soundAssets); i++)
{
SoundAsset_Check(&soundAssets[i]);
}
}
static const struct AssetSet soundAssetSet = {
SoundAssets_CheckExistence,
SoundAssets_DownloadAssets,
SoundAssets_CheckStatus
};
/*########################################################################################################################*
@ -764,15 +858,6 @@ static void DefaultZip_CheckExistence(void) {
}
}
void Resources_CheckExistence(void) {
Resources_Count = 0;
Resources_Size = 0;
DefaultZip_CheckExistence();
MusicResources_CheckExistence();
SoundResources_CheckExistence();
}
/*########################################################################################################################*
*-----------------------------------------------------------Fetcher-------------------------------------------------------*
@ -781,17 +866,35 @@ cc_bool Fetcher_Working, Fetcher_Completed, Fetcher_Failed;
int Fetcher_Downloaded;
FetcherErrorCallback Fetcher_ErrorCallback;
/* TODO: array of asset sets */
static const struct AssetSet* const asset_sets[] = {
&musicAssetSet,
&soundAssetSet
};
void Resources_CheckExistence(void) {
int i;
Resources_Count = 0;
Resources_Size = 0;
DefaultZip_CheckExistence();
for (i = 0; i < Array_Elems(asset_sets); i++)
{
asset_sets[i]->CheckExistence();
}
}
const char* Fetcher_RequestName(int reqID) {
int i;
for (i = 0; i < Array_Elems(defaultZipSources); i++) {
if (reqID == defaultZipSources[i].reqID) return defaultZipSources[i].name;
}
for (i = 0; i < Array_Elems(musicResources); i++) {
if (reqID == musicResources[i].reqID) return musicResources[i].name;
for (i = 0; i < Array_Elems(musicAssets); i++) {
if (reqID == musicAssets[i].reqID) return musicAssets[i].name;
}
for (i = 0; i < Array_Elems(soundResources); i++) {
if (reqID == soundResources[i].reqID) return soundResources[i].name;
for (i = 0; i < Array_Elems(soundAssets); i++) {
if (reqID == soundAssets[i].reqID) return soundAssets[i].name;
}
return NULL;
}
@ -812,13 +915,9 @@ void Fetcher_Run(void) {
defaultZipSources[i].reqID = Http_AsyncGetData(&url, 0);
}
for (i = 0; i < Array_Elems(musicResources); i++) {
if (musicResources[i].downloaded) continue;
musicResources[i].reqID = MusicResource_Download(musicResources[i].hash);
}
for (i = 0; i < Array_Elems(soundResources); i++) {
if (allSoundsExist) continue;
soundResources[i].reqID = SoundResource_Download(soundResources[i].hash);
for (i = 0; i < Array_Elems(asset_sets); i++)
{
asset_sets[i]->DownloadAssets();
}
}
@ -871,23 +970,6 @@ static void Fetcher_CheckFile(struct ZipfileSource* file) {
if (file->last) DefaultZip_Create();
}
static void Fetcher_CheckMusic(struct MusicResource* music) {
struct HttpRequest item;
if (!Fetcher_Get(music->reqID, &item)) return;
music->downloaded = true;
MusicResource_Save(music->name, &item);
HttpRequest_Free(&item);
}
static void Fetcher_CheckSound(const struct SoundResource* sound) {
struct HttpRequest item;
if (!Fetcher_Get(sound->reqID, &item)) return;
SoundPatcher_Save(sound->name, &item);
HttpRequest_Free(&item);
}
/* TODO: Implement this.. */
/* TODO: How expensive is it to constantly do 'Get' over and over */
void Fetcher_Update(void) {
@ -898,13 +980,9 @@ void Fetcher_Update(void) {
Fetcher_CheckFile(&defaultZipSources[i]);
}
for (i = 0; i < Array_Elems(musicResources); i++) {
if (musicResources[i].downloaded) continue;
Fetcher_CheckMusic(&musicResources[i]);
}
for (i = 0; i < Array_Elems(soundResources); i++) {
Fetcher_CheckSound(&soundResources[i]);
for (i = 0; i < Array_Elems(asset_sets); i++)
{
asset_sets[i]->CheckStatus();
}
if (Fetcher_Downloaded != Resources_Count) return;

View File

@ -118,7 +118,7 @@ static void SPConnection_BeginConnect(void) {
static const cc_string logName = String_FromConst("Singleplayer");
RNGState rnd;
Chat_SetLogName(&logName);
Game_UseCPEBlocks = Game_UseCPE;
Game_UseCPEBlocks = Game_Version.HasCPE;
/* For when user drops a map file onto ClassiCube.exe */
if (SP_AutoloadMap.length) {