Fix full URL skins for non-humanoid disappearing when changing model of an entity

This commit is contained in:
UnknownShadow200 2018-10-01 15:48:16 +10:00
parent c8b081f348
commit ab9fe3c14f
8 changed files with 85 additions and 85 deletions

View File

@ -16,20 +16,10 @@ namespace ClassicalSharp.Entities {
anim = new AnimatedComponent(game, this); anim = new AnimatedComponent(game, this);
} }
/// <summary> The model of this entity. (used for collision detection and rendering) </summary>
public IModel Model; public IModel Model;
public string SkinName, ModelName;
/// <summary> The name of the model of this entity. </summary>
public string ModelName;
/// <summary> BlockID if model name is a vaid block id. </summary>
/// <remarks> This avoids needing to repeatedly parse ModelName as a byte. </remarks>
public BlockID ModelBlock; public BlockID ModelBlock;
/// <summary> Scale applied to the model for collision detection and rendering. </summary>
public Vector3 ModelScale = new Vector3(1.0f); public Vector3 ModelScale = new Vector3(1.0f);
/// <summary> Returns the size of the model that is used for collision detection. </summary>
public Vector3 Size; public Vector3 Size;
public int TextureId, MobTextureId; public int TextureId, MobTextureId;
@ -132,6 +122,10 @@ namespace ClassicalSharp.Entities {
ParseScale(scale); ParseScale(scale);
Model.RecalcProperties(this); Model.RecalcProperties(this);
UpdateModelBounds(); UpdateModelBounds();
if (SkinName != null && Utils.IsUrlPrefix(SkinName, 0)) {
MobTextureId = TextureId;
}
} }
public void UpdateModelBounds() { public void UpdateModelBounds() {

View File

@ -14,7 +14,7 @@ namespace ClassicalSharp.Entities {
public abstract class Player : Entity { public abstract class Player : Entity {
public string DisplayName, SkinName; public string DisplayName;
protected Texture nameTex; protected Texture nameTex;
internal bool fetchedSkin; internal bool fetchedSkin;

View File

@ -91,7 +91,7 @@ static ReturnCode Sound_ReadWaveData(struct Stream* stream, struct Sound* snd) {
snd->Format.BitsPerSample = Stream_GetU16_LE(&tmp[14]); snd->Format.BitsPerSample = Stream_GetU16_LE(&tmp[14]);
size -= WAV_FMT_SIZE; size -= WAV_FMT_SIZE;
} else if (fourCC == WAV_FourCC('d','a','t','a')) { } else if (fourCC == WAV_FourCC('d','a','t','a')) {
snd->Data = Mem_Alloc(size, sizeof(UInt8), "WAV sound data"); snd->Data = Mem_Alloc(size, 1, "WAV sound data");
snd->DataSize = size; snd->DataSize = size;
return Stream_Read(stream, snd->Data, size); return Stream_Read(stream, snd->Data, size);
} }
@ -498,8 +498,9 @@ static Int32 AudioManager_GetVolume(const char* volKey, const char* boolKey) {
return volume; return volume;
} }
static void AudioManager_FilesCallback(const String* filename, void* obj) { static void AudioManager_FilesCallback(const String* path, void* obj) {
StringsBuffer_Add(&files, filename); String file = *path; Utils_UNSAFE_GetFilename(&file);
StringsBuffer_Add(&files, &file);
} }
static void AudioManager_Init(void) { static void AudioManager_Init(void) {

View File

@ -72,6 +72,7 @@ void Entity_Init(struct Entity* e) {
e->ModelScale = Vector3_Create1(1.0f); e->ModelScale = Vector3_Create1(1.0f);
e->uScale = 1.0f; e->uScale = 1.0f;
e->vScale = 1.0f; e->vScale = 1.0f;
e->SkinNameRaw[0] = '\0';
} }
Vector3 Entity_GetEyePosition(struct Entity* e) { Vector3 Entity_GetEyePosition(struct Entity* e) {
@ -153,6 +154,8 @@ void Entity_SetModel(struct Entity* e, const String* model) {
e->Model->RecalcProperties(e); e->Model->RecalcProperties(e);
Entity_UpdateModelBounds(e); Entity_UpdateModelBounds(e);
String skin = String_FromRawArray(e->SkinNameRaw);
if (Utils_IsUrlPrefix(&skin, 0)) { e->MobTextureId = e->TextureId; }
} }
void Entity_UpdateModelBounds(struct Entity* e) { void Entity_UpdateModelBounds(struct Entity* e) {
@ -546,14 +549,15 @@ static void Player_DrawName(struct Player* player) {
static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) { static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
struct Entity* entity = &player->Base; struct Entity* entity = &player->Base;
String skin = String_FromRawArray(player->SkinNameRaw); String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i; Int32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i] || Entities_List[i] == entity) continue; if (!Entities_List[i] || Entities_List[i] == entity) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue; if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i]; struct Player* p = (struct Player*)Entities_List[i];
String pSkin = String_FromRawArray(p->SkinNameRaw); String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (String_Equals(&skin, &pSkin)) return p; if (String_Equals(&skin, &pSkin)) return p;
} }
return NULL; return NULL;
@ -561,14 +565,15 @@ static struct Player* Player_FirstOtherWithSameSkin(struct Player* player) {
static struct Player* Player_FirstOtherWithSameSkinAndFetchedSkin(struct Player* player) { static struct Player* Player_FirstOtherWithSameSkinAndFetchedSkin(struct Player* player) {
struct Entity* entity = &player->Base; struct Entity* entity = &player->Base;
String skin = String_FromRawArray(player->SkinNameRaw); String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i; Int32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i] || Entities_List[i] == entity) continue; if (!Entities_List[i] || Entities_List[i] == entity) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue; if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i]; struct Player* p = (struct Player*)Entities_List[i];
String pSkin = String_FromRawArray(p->SkinNameRaw); String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (p->FetchedSkin && String_Equals(&skin, &pSkin)) return p; if (p->FetchedSkin && String_Equals(&skin, &pSkin)) return p;
} }
return NULL; return NULL;
@ -585,10 +590,8 @@ static void Player_ApplySkin(struct Player* player, struct Player* from) {
/* Custom mob textures */ /* Custom mob textures */
dst->MobTextureId = NULL; dst->MobTextureId = NULL;
String skin = String_FromRawArray(player->SkinNameRaw); String skin = String_FromRawArray(dst->SkinNameRaw);
if (Utils_IsUrlPrefix(&skin, 0)) { if (Utils_IsUrlPrefix(&skin, 0)) { dst->MobTextureId = dst->TextureId; }
dst->MobTextureId = dst->TextureId;
}
} }
void Player_ResetSkin(struct Player* player) { void Player_ResetSkin(struct Player* player) {
@ -601,14 +604,16 @@ void Player_ResetSkin(struct Player* player) {
/* Apply or reset skin, for all players with same skin */ /* Apply or reset skin, for all players with same skin */
static void Player_SetSkinAll(struct Player* player, bool reset) { static void Player_SetSkinAll(struct Player* player, bool reset) {
String skin = String_FromRawArray(player->SkinNameRaw); struct Entity* entity = &player->Base;
String skin = String_FromRawArray(entity->SkinNameRaw);
Int32 i; Int32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) { for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
if (!Entities_List[i]) continue; if (!Entities_List[i]) continue;
if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue; if (Entities_List[i]->EntityType != ENTITY_TYPE_PLAYER) continue;
struct Player* p = (struct Player*)Entities_List[i]; struct Player* p = (struct Player*)Entities_List[i];
String pSkin = String_FromRawArray(p->SkinNameRaw); String pSkin = String_FromRawArray(p->Base.SkinNameRaw);
if (!String_Equals(&skin, &pSkin)) continue; if (!String_Equals(&skin, &pSkin)) continue;
if (reset) { if (reset) {
@ -670,23 +675,23 @@ static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) {
*bmp = scaled; *bmp = scaled;
} }
static void Player_CheckSkin(struct Player* player) { static void Player_CheckSkin(struct Player* p) {
struct Entity* entity = &player->Base; struct Entity* e = &p->Base;
String skin = String_FromRawArray(player->SkinNameRaw); String skin = String_FromRawArray(e->SkinNameRaw);
if (!player->FetchedSkin && entity->Model->UsesSkin) { if (!p->FetchedSkin && e->Model->UsesSkin) {
struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(player); struct Player* first = Player_FirstOtherWithSameSkinAndFetchedSkin(p);
if (!first) { if (!first) {
AsyncDownloader_GetSkin(&skin, &skin); AsyncDownloader_GetSkin(&skin, &skin);
} else { } else {
Player_ApplySkin(player, first); Player_ApplySkin(p, first);
} }
player->FetchedSkin = true; p->FetchedSkin = true;
} }
struct AsyncRequest item; struct AsyncRequest item;
if (!AsyncDownloader_Get(&skin, &item)) return; if (!AsyncDownloader_Get(&skin, &item)) return;
if (!item.ResultData) { Player_SetSkinAll(player, true); return; } if (!item.ResultData) { Player_SetSkinAll(p, true); return; }
String url = String_FromRawArray(item.URL); String url = String_FromRawArray(item.URL);
struct Stream mem; Bitmap bmp; struct Stream mem; Bitmap bmp;
@ -698,19 +703,19 @@ static void Player_CheckSkin(struct Player* player) {
Mem_Free(bmp.Scan0); return; Mem_Free(bmp.Scan0); return;
} }
Gfx_DeleteTexture(&entity->TextureId); Gfx_DeleteTexture(&e->TextureId);
Player_SetSkinAll(player, true); Player_SetSkinAll(p, true);
Player_EnsurePow2(player, &bmp); Player_EnsurePow2(p, &bmp);
entity->SkinType = Utils_GetSkinType(&bmp); e->SkinType = Utils_GetSkinType(&bmp);
if (entity->SkinType == SKIN_INVALID) { if (e->SkinType == SKIN_INVALID) {
Player_SetSkinAll(player, true); Player_SetSkinAll(p, true);
} else { } else {
if (entity->Model->UsesHumanSkin) { if (e->Model->UsesHumanSkin) {
Player_ClearHat(&bmp, entity->SkinType); Player_ClearHat(&bmp, e->SkinType);
} }
entity->TextureId = Gfx_CreateTexture(&bmp, true, false); e->TextureId = Gfx_CreateTexture(&bmp, true, false);
Player_SetSkinAll(player, false); Player_SetSkinAll(p, false);
} }
Mem_Free(bmp.Scan0); Mem_Free(bmp.Scan0);
} }
@ -736,10 +741,10 @@ static void Player_ContextRecreated(struct Entity* e) {
Player_UpdateNameTex(player); Player_UpdateNameTex(player);
} }
void Player_SetName(struct Player* player, const String* name, const String* skin) { void Player_SetName(struct Player* p, const String* name, const String* skin) {
String p_name = String_ClearedArray(player->DisplayNameRaw); String p_name = String_ClearedArray(p->DisplayNameRaw);
String_AppendString(&p_name, name); String_AppendString(&p_name, name);
String p_skin = String_ClearedArray(player->SkinNameRaw); String p_skin = String_ClearedArray(p->Base.SkinNameRaw);
String_AppendString(&p_skin, skin); String_AppendString(&p_skin, skin);
} }

View File

@ -86,6 +86,7 @@ struct Entity {
struct Matrix Transform; struct Matrix Transform;
struct AnimatedComp Anim; struct AnimatedComp Anim;
char SkinNameRaw[STRING_SIZE];
}; };
void Entity_Init(struct Entity* entity); void Entity_Init(struct Entity* entity);
@ -126,7 +127,7 @@ void TabList_MakeComponent(struct IGameComponent* comp);
#define TabList_UNSAFE_GetPlayer(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_PlayerNames[id]); #define TabList_UNSAFE_GetPlayer(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_PlayerNames[id]);
#define TabList_UNSAFE_GetList(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_ListNames[id]); #define TabList_UNSAFE_GetList(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_ListNames[id]);
#define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_GroupNames[id]); #define TabList_UNSAFE_GetGroup(id) StringsBuffer_UNSAFE_Get(&TabList_Buffer, TabList_GroupNames[id]);
#define Player_Layout struct Entity Base; char DisplayNameRaw[STRING_SIZE]; char SkinNameRaw[STRING_SIZE]; bool FetchedSkin; struct Texture NameTex; #define Player_Layout struct Entity Base; char DisplayNameRaw[STRING_SIZE]; bool FetchedSkin; struct Texture NameTex;
/* Represents a player entity. */ /* Represents a player entity. */
struct Player { Player_Layout }; struct Player { Player_Layout };

View File

@ -308,7 +308,7 @@ static ReturnCode Nbt_ReadTag(UInt8 typeId, bool readTagName, struct Stream* str
if (tag.DataSize < NBT_SMALL_SIZE) { if (tag.DataSize < NBT_SMALL_SIZE) {
res = Stream_Read(stream, tag.DataSmall, tag.DataSize); res = Stream_Read(stream, tag.DataSmall, tag.DataSize);
} else { } else {
tag.DataBig = Mem_Alloc(tag.DataSize, sizeof(UInt8), "NBT data"); tag.DataBig = Mem_Alloc(tag.DataSize, 1, "NBT data");
res = Stream_Read(stream, tag.DataBig, tag.DataSize); res = Stream_Read(stream, tag.DataBig, tag.DataSize);
if (res) { Mem_Free(tag.DataBig); } if (res) { Mem_Free(tag.DataBig); }
} }
@ -719,7 +719,7 @@ static ReturnCode Dat_ReadFieldData(struct Stream* stream, struct JFieldDesc* fi
if ((res = Stream_ReadU32_BE(stream, &count))) return res; if ((res = Stream_ReadU32_BE(stream, &count))) return res;
field->Value_Size = count; field->Value_Size = count;
field->Value_Ptr = Mem_Alloc(count, sizeof(UInt8), ".dat map blocks"); field->Value_Ptr = Mem_Alloc(count, 1, ".dat map blocks");
res = Stream_Read(stream, field->Value_Ptr, count); res = Stream_Read(stream, field->Value_Ptr, count);
if (res) { Mem_Free(field->Value_Ptr); return res; } if (res) { Mem_Free(field->Value_Ptr); return res; }
} break; } break;

View File

@ -1399,10 +1399,12 @@ static void TexturePackScreen_EntryClick(void* screen, void* widget) {
ListScreen_SetCurrentIndex(s, idx); ListScreen_SetCurrentIndex(s, idx);
} }
static void TexturePackScreen_FilterFiles(const String* filename, void* obj) { static void TexturePackScreen_FilterFiles(const String* path, void* obj) {
String zip = String_FromConst(".zip"); String zip = String_FromConst(".zip");
if (!String_CaselessEnds(filename, &zip)) return; if (!String_CaselessEnds(path, &zip)) return;
StringsBuffer_Add((StringsBuffer*)obj, filename);
String file = *path; Utils_UNSAFE_GetFilename(&file);
StringsBuffer_Add((StringsBuffer*)obj, &file);
} }
struct Screen* TexturePackScreen_MakeInstance(void) { struct Screen* TexturePackScreen_MakeInstance(void) {
@ -1545,13 +1547,15 @@ struct Screen* HotkeyListScreen_MakeInstance(void) {
/*########################################################################################################################* /*########################################################################################################################*
*----------------------------------------------------LoadLevelScreen------------------------------------------------------* *----------------------------------------------------LoadLevelScreen------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void LoadLevelScreen_FilterFiles(const String* filename, void* obj) { static void LoadLevelScreen_FilterFiles(const String* path, void* obj) {
String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl"); String cw = String_FromConst(".cw"); String lvl = String_FromConst(".lvl");
String fcm = String_FromConst(".fcm"); String dat = String_FromConst(".dat"); String fcm = String_FromConst(".fcm"); String dat = String_FromConst(".dat");
if (!(String_CaselessEnds(filename, &cw) || String_CaselessEnds(filename, &lvl) if (!(String_CaselessEnds(path, &cw) || String_CaselessEnds(path, &lvl)
|| String_CaselessEnds(filename, &fcm) || String_CaselessEnds(filename, &dat))) return; || String_CaselessEnds(path, &fcm) || String_CaselessEnds(path, &dat))) return;
StringsBuffer_Add((StringsBuffer*)obj, filename);
String file = *path; Utils_UNSAFE_GetFilename(&file);
StringsBuffer_Add((StringsBuffer*)obj, &file);
} }
void LoadLevelScreen_LoadMap(const String* path) { void LoadLevelScreen_LoadMap(const String* path) {

View File

@ -306,28 +306,27 @@ bool File_Exists(const String* path) {
return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY); return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY);
} }
ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) { ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
char fileBuffer[MAX_PATH + 10]; char pathBuffer[MAX_PATH + 10];
String file = String_FromArray(fileBuffer); String path = String_FromArray(pathBuffer);
/* Need to append \* to search for files in directory */ /* Need to append \* to search for files in directory */
String_Format1(&file, "%s\\*", path); String_Format1(&path, "%s\\*", dirPath);
WCHAR str[300]; Platform_ConvertString(str, &file); WCHAR str[300]; Platform_ConvertString(str, &path);
WIN32_FIND_DATAW entry; WIN32_FIND_DATAW entry;
HANDLE find = FindFirstFileW(str, &entry); HANDLE find = FindFirstFileW(str, &entry);
if (find == INVALID_HANDLE_VALUE) return GetLastError(); if (find == INVALID_HANDLE_VALUE) return GetLastError();
do { do {
if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
file.length = 0; path.length = 0;
String_Format2(&path, "%s%r", dirPath, &Directory_Separator);
Int32 i; Int32 i;
for (i = 0; i < MAX_PATH && entry.cFileName[i]; i++) { for (i = 0; i < MAX_PATH && entry.cFileName[i]; i++) {
String_Append(&file, Convert_UnicodeToCP437(entry.cFileName[i])); String_Append(&path, Convert_UnicodeToCP437(entry.cFileName[i]));
} }
callback(&path, obj);
Utils_UNSAFE_GetFilename(&file);
callback(&file, obj);
} while (FindNextFileW(find, &entry)); } while (FindNextFileW(find, &entry));
ReturnCode result = GetLastError(); /* return code from FindNextFile */ ReturnCode result = GetLastError(); /* return code from FindNextFile */
@ -418,27 +417,25 @@ bool File_Exists(const String* path) {
return stat(str, &sb) == 0 && S_ISREG(sb.st_mode); return stat(str, &sb) == 0 && S_ISREG(sb.st_mode);
} }
ReturnCode Directory_Enum(const String* path, void* obj, Directory_EnumCallback callback) { ReturnCode Directory_Enum(const String* dirPath, void* obj, Directory_EnumCallback callback) {
char str[600]; Platform_ConvertString(str, path); char str[600]; Platform_ConvertString(str, dirPath);
DIR* dirPtr = opendir(str); DIR* dirPtr = opendir(str);
if (!dirPtr) return errno; if (!dirPtr) return errno;
char fileBuffer[FILENAME_SIZE]; char pathBuffer[FILENAME_SIZE];
String file = String_FromArray(fileBuffer); String path = String_FromArray(pathBuffer);
struct dirent* entry; struct dirent* entry;
/* TODO: does this also include subdirectories */ /* TODO: does this also include subdirectories */
while (entry = readdir(dirPtr)) { while (entry = readdir(dirPtr)) {
UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue); UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue);
file.length = 0; path.length = 0;
String_DecodeUtf8(&file, entry->d_name, len); String_DecodeUtf8(&path, entry->d_name, len);
/* exlude . and .. paths */ /* exlude . and .. paths */
if (file.length == 1 && file.buffer[0] == '.') continue; if (path.length == 1 && path.buffer[0] == '.') continue;
if (file.length == 2 && file.buffer[0] == '.' && file.buffer[1] == '.') continue; if (path.length == 2 && path.buffer[0] == '.' && path.buffer[1] == '.') continue;
callback(&path, obj);
Utils_UNSAFE_GetFilename(&file);
callback(&file, obj);
} }
int result = errno; /* return code from readdir */ int result = errno; /* return code from readdir */
@ -734,12 +731,10 @@ void Font_Free(FontDesc* desc) {
desc->Handle = NULL; desc->Handle = NULL;
} }
static void Font_DirCallback(const String* filename, void* obj) { static void Font_DirCallback(const String* srcPath, void* obj) {
char pathBuffer[FILENAME_SIZE + 1]; char pathBuffer[FILENAME_SIZE + 1];
String path = String_NT_Array(pathBuffer); String path = String_NT_Array(pathBuffer);
String* dir = obj; String_Copy(&path, srcPath);
String_Format2(&path, "%s%s", dir, filename);
path.buffer[path.length] = '\0'; path.buffer[path.length] = '\0';
FT_Face face; FT_Face face;
@ -828,8 +823,8 @@ Size2D Platform_TextDraw(struct DrawTextArgs* args, Bitmap* bmp, Int32 x, Int32
#if CC_BUILD_WIN #if CC_BUILD_WIN
static void Font_Init(void) { static void Font_Init(void) {
FT_Error err = FT_Init_FreeType(&lib); FT_Error err = FT_Init_FreeType(&lib);
String dir = String_FromConst("C:\\Windows\\fonts\\"); String dir = String_FromConst("C:\\Windows\\fonts");
Directory_Enum(&dir, &dir, Font_DirCallback); Directory_Enum(&dir, NULL, Font_DirCallback);
} }
#elif CC_BUILD_NIX #elif CC_BUILD_NIX
#endif #endif