Jump to content
Korean Random

Monstrofil

User
  • Content Count

    97
  • Joined

  • Last visited

  • Days Won

    7

Monstrofil last won the day on September 14 2023

Monstrofil had the most liked content!

Community Reputation

70

Contacts

  • Nick
    Monstrofil

Recent Profile Visitors

8,574 profile views
  1. С обновлением 12.9 кораблики к каждому пакету перед заголовками начали дописывать int32 (?). Сначала думал что это какая-то защита, но сервер принял сообщение даже с нулями вместо первых 4 байт. Предназначение пока непонятно. 45a55fea0100000502b0cc00000000040001110112f1d0fb63c1db892d050d4ed07ca103ed67214bcb1b6524ea69a0c70fc057818ed12359a9d6661898eff2621f4aa5e5ebb786309e8cfa18f88ce8e441b36130dba83f936df528cac18dbfba4ca7cf6f5e3ea40539ebaf7bfd6d3e9ae8ff910777f4c37e0d24d671f18b63f8f341421b0cbcc9a53d5c7c7264350aaae485913774d80ae329dc47ed0fb81405c13096cc8028d9fe6d86cd952aa38543c4802a600e6cc79513fc9598daab9a70701d8f72f6ef952d2214abcc94933019729646456562bfeb6e2f541082794fc9a930406369b649b238f1648775373b08a674f069a2e3def62b0c1c82ef8624bed1b248f62c9102b0ba05ee659bd4e98f5e33bb7e3aca0ad985d78f21c167bfa929b2bbfc050f9515b3701752ae0acb0badada3afe60f45ec5998d3499534eea89b4f0ba082a0e8d6b7528f5664965db3e379f9ba52324c0ca842aced0bd9c5674054ccd6918ae5e21560eb7978f1a115aa5564d08bf457037cf10f13ee56c6f3232ff27132efde88cbac6ae9b3a114313de7f59f48e28630a85c634cc827d81af7051fd739fb02a2051fe598832c0ff270f45113cda56caa8a8801b4a700546a21026e8094a267230b23a79882be7e52c16115d432646180bd3bde1d0b02a7dd5387f03d877b2e500d21fce6c366786932369741baf771fa014344d9bf97b11c6bf18dba2e97738e30941f060d791fc7cd5ce2750200 55867fee0100000502b1cc00000000040001110153c7eae8ea610ecbbf30e7003518e06d2b2ee639ddd8ec5953de6eab6e0a049316996b16f5073a1ceb409815da98726a8a84caf8e19096df688d7b53e399b2902a08014b4fca5cc5a4bf32e84436bc19c44cf290fea76b352be79d039e49891ed48c48998d3e01d36f19b523eaad9914cce4a6c6eca7507af9f9967cc297a9e19057ccaace6a55f5244d57ca5bb8d65b75a062a44271d7471e19415b673d94cc54db5c3e84a19e685a5f517d521a146d3be32692663a166414618222b2942abe5e7cd1bf8af7cc50c6fb10dbabd1b2f0faaca15aadcf64f8fde126a1182c05e7480aab602e5b074d06af793df5d3e1cd171bbbd8963bea0e1ded7917326b0ee41bf87a3ba1063dafd465c6766f19ed0de9596439fde0f108eb17b0f5edf3f35044bbc1b1dd3b54e247e5308bc4a32d98e31d285784bcc4a679a8bca298c6a4b5fafa071f682438395b398115e186394197fa7f97fd178477f28093efe3c9a5d2ddcdfe3ccbb2cd10c9164fa348ed25030e1e79b07a0e3cdffebafe460382ce8a560d7a84a317d700a532a90e433e305f4d951e5ccfb5c76621f299c75058cd90b7bc6e38d123591d1aa95c7f89079a5ad3f21408c7bd805904d5bc11e382ef1ea4f3734a16f8d5a556e1bf2594aceb7666900b836f208b24a07ba792671d6e15d2848e28ccae8c7f4248a2bcdb81233e7b4e4cc1c9e189e51a7ba4dedc48c8ac0200 65e31fe20100000502b2cc00000000040001110150ad7302089bb2af9531f01635d8e0f0c6892f2de8d24dc8ae022d68a8eeaaa726a4f5e3809b00df0bcae1293508d0122b526fa8f344563ece5adf32811272e9e8a95ebe5b43e5a94d1dd69e2954cff612a41d08e6f3a91422a4dc6be9377c6d7123ecb4fa0b45f5e0f7fffb4a8c2cedfb3f530422ee85ebdb9babdfabf8e303b67866fced552f9d967523229990ac5d7b3598ca7509cf1461b32e5ebc03f9f2d2451ec5ac40c37dac710615b0b56f81eb07b0b09d054c2e0429f8ae647ef265ec7c64185201846bce884c4d4ce9af868fc635e02a1021f5e07b5162dabec19fc4b3b6cb1984b7fae9689671b2dc9e5305f6351808e7c97a4b6d739684f8d9b6373a0fab95ce65194b51590f66266b638ac121b2e6b41613d8ab44b776dcf03afc74de0c4d791ead318eff67fae824f6b4db3250db8870b7dfd2ffccdf015df4bc2412e55abbf1e4b21885761ce1af3890fd239e1d0f7685fd04e29c9b8854bc6bc07d37e66c779e1f3e344ff49793a6c6fb510875d9e29eeabdeefbfa45907a98baf96e11e81cf23a0099a1babc82b28153b52dc84b65909bc20d3179ae5b8b80fe0e0406103d241ab2a1d7751427168bb9b975e1aa4c43fb2b3342f4fcb2dcd36178ec190049bbf3c70dbbe86e1ef13195d68f4fa49e462adbf5a7b546d274673f664ba39180c99c59151458cdea0a468368ad2803aefd7059541ceae8098d0200 75c03fe60100000502b3cc0000000004000111018a55691fd774efd48300993088f814afb77192e602c9776bb88197c239a08e9ba636b3ce2156befc344712813b19e38b956efbe3d9972729fff05189641aa1c733e4158cd2d8a134824ae52bf9265033ab02de969156f081048c6d1d5735bbbeea94b829103da7f221474fd71e74f39e608054ad91ed5ad77beca9be53cd4ece92033b598d3648f355337e213c823f579683e47181c83da50e0d5c87daccb9dc8fd50311d8555feac50ac71ec9edcee583fe6e189d84f8504131e3517c8049771dfe25631be218a8d0b71b82ffd079424005dbef520644bdbdb97131cdd63806c20dc4ffe6752f2b83eaaab411935d9fe3c98034553cf9853eced059322c8b23815f12737b02e3aa409073aed25141726cc38e9f3a50f71ce4d28145a3cfc1d48ba2e1e04ba02f070eb8eb5c730398b0498b03088b0626c1e1a78e96989b07bc9bd5cc81885055f7c291471977156f3355ea0e73283459e1a497aae91b1b8376225e84e1afaad30d06c118eea5a98af246102f893858797f6dab9863e90d8c43f39114522a8181e5db5b11c4c68c646765c957b7aaa132b7155a6025895c31d9118311e56a6b0b9410427defbec9e1874f4088bd84728f616d24baa63d6bf4a0beb8b1678b3a2f00c3a22c286c5848ebdde4bab74851deb7284629726a4f8a87f64dfba24bc90dd496b485138210480ab8309a3577b06d897e1b6bb2b650017c0200 p.s. обратно тоже приходят пакеты с таким дополнительным заголовком. 9f4d1f9b0000ff06000000deafbeaf4600
  2. Новый battle result не используется на replayswows.com, а поддерживать такое количество констант относительно каждой новой версии клиента вхолостую я не хочу.
  3. On the other hand, you need cell and base scripts anyway if you want to run WOT with your own hand-made server :)
  4. "version mismatch" means that server accepted your login message, but either md5 sum of entity_defs is incorrect (did you copy those from wot client?) or hardcoded login_version constant was not changed to match wot client (did you do that?)
  5. entities.xml - перечень entity используемых клиентом *.def - описание методов и свойств entity, описание типов данных в "сообщениях" <makeDenunciation> <Exposed></Exposed> <Arg> OBJECT_ID </Arg> <Arg> INT32 </Arg> <Arg> INT8 </Arg> </makeDenunciation> ^^ метод makeDenunciation, размер 9 байт (OBJECT_ID (4) + INT32 (4) + INT (8), именно в таком порядке и с такими размерами аргументы будут запакованы в сообщении messageID - порядковый номер сообщения (подиндекс в entityProperty или entityMethod) конкретной entity, сообщения должны быть отсортированы по их размеру (для методов - сумме размеров всех аргументов, для свойств - размеру свойства, размеры вычисляются из базовых типов, кастомные типы прописываются в alias.xml). Привязка к messageID вычисляется примерно тут. https://github.com/Monstrofil/replays_unpack/blob/master/replay_unpack/core/entity_def/entity_description.py#L119 p.s. "но знаний C# и способности разбираться в чужом коде не хватает" --> так или иначе придется разбираться, ну или переписывать с ноля, но тут я только пожелаю удачи и вернетесь вы через полгода =) p.p.s. вот этот readme как раз про messageId... https://github.com/Monstrofil/replays_unpack/blob/master/docs/Getting exposed index for properties and methods.md
  6. Ага, оно самое. Но спидометр это не исправило =/
  7. Когда-то давно натыкался на ошибочно запакованные в файлы клиента сорсы шейдеров салолётиков, сегодня случайно наткнулся повторно. Закину сюда в тему, может пригодится кому-нибудь. #include "stdinclude.fxh" #define DUAL_UV 1 #if SKINNED #include "skinned_effect_include.fxh" #else #include "unskinned_effect_include.fxh" #endif // BW_DIFFUSE_LIGHTING BW_SPECULAR_LIGHTING BW_ARTIST_EDITABLE_DOUBLE_SIDED BW_ARTIST_EDITABLE_DIFFUSE_MAP BW_ARTIST_EDITABLE_NORMAL_MAP texture reflectionMap : EnvMap; BW_ARTIST_EDITABLE_REFLECTION_AMOUNT BW_ARTIST_EDITABLE_ALPHA_TEST BW_ARTIST_EDITABLE_ADDRESS_MODE(BW_WRAP) sampler reflectionSampler = BW_SAMPLER(reflectionMap, WRAP) samplerCUBE reflectionCubeSampler = BW_SAMPLER_NON_MIPMAP_BIASED( reflectionMap, CLAMP ) //samplerCUBE reflectionCubeSampler = BW_SAMPLER( reflectionMap, CLAMP ) BW_ARTIST_EDITABLE_FRESNEL #include "common.fxh" texture specularPowerMap < bool artistEditable = true; string UIName = "Specular Parameters Map"; string UIDesc = "The specular and other parameters"; >; #ifndef AIRCRAFT_OBJECT texture camuflageMap : CamuflageMap; texture decals : DecalMap; texture selfShadowMap : SelfShadow; #endif float glossinessOffset : GlossinessOffset; #if defined(AIRCRAFT_OBJECT) float4 bottomColor : BottomColor; #endif // TODO #include "normalmap_chrome.fxh" OR "material_helpers.fxh" instead of the "materialSpecular" declaration /* float materialSpecular < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0.0; */ float4 materialSpecular\ < \ bool artistEditable = true;\ string UIWidget = "Color"; \ string UIName = "Specular Colour";\ string UIDesc = "The specular colour for the material";\ float UIMin = 0;\ float UIMax = 2;\ int UIDigits = 1;\ > = {1,1,1,1}; float selfIllumination < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0.0; /* float specularPower < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0.0; */ /* float glossiness_shift < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0; */ float normalmap_weight < bool artistEditable = true; string UIName = "Normalmap Weight"; string UIDesc = "Normalmap Weight"; float UIMin = 0; float UIMax = 1; int UIDigits = 2; > = 1.0; bool gloss_const_enabled < bool artistEditable = true; string UIName = "Glossiness Constant Enabled"; string UIDesc = "Whether to use the constant value for glossiness"; > = false; float gloss_const < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0.5; /* float gloss_const_weight < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0; */ /* float cubemap_saturation < bool artistEditable = true; string UIName = "Not used"; string UIDesc = "Not used"; > = 0; */ sampler diffuseSampler = BW_SAMPLER(diffuseMap, BW_TEX_ADDRESS_MODE) sampler normalSampler = BW_SAMPLER(normalMap, BW_TEX_ADDRESS_MODE) sampler specularPowerSampler = BW_SAMPLER(specularPowerMap, BW_TEX_ADDRESS_MODE) #ifndef AIRCRAFT_OBJECT sampler camuflageSampler = BW_SAMPLER(camuflageMap, BW_TEX_ADDRESS_MODE) sampler decalSampler = BW_SAMPLER(decals, BW_TEX_ADDRESS_MODE) #ifndef AIRCRAFT_NO_SELFSHADOW sampler selfShadowSampler = BW_SAMPLER(selfShadowMap, BW_TEX_ADDRESS_MODE) #endif #endif float4x4 worldViewProj : WorldViewProjection; float4x4 worldView : WorldView; struct PS_INPUT { float4 pos : POSITION; float2 tc : TEXCOORD0; float3 wPos : TEXCOORD1; float3 vPos : TEXCOORD2; float3 vBinormal : TEXCOORD3; float3 vTangent : TEXCOORD4; float3 vNormal : TEXCOORD5; float2 tc2: TEXCOORD8; }; #if SKINNED PS_INPUT vs_main_uv1(VertexXYZNUVIIIWWTB i) #else PS_INPUT vs_main_uv1(VertexXYZNUVTB i) #endif { PS_INPUT o=(PS_INPUT)0; PROJECT_POSITION( o.pos ) o.tc = i.tc; o.tc2 = float2(0,0); o.wPos = worldPos.xyz; o.vPos = mul(float4(worldPos.xyz, 1.0f), g_viewMat); // // // #if SKINNED CALCULATE_TS_MATRIX float3 vBinormal = normalize(mul(tsMatrix[1], g_viewMat)).xyz; float3 vTangent = normalize(mul(tsMatrix[0], g_viewMat)).xyz; float3 vNormal = normalize(mul(tsMatrix[2], g_viewMat)).xyz; #else float3 vBinormal = normalize(mul(i.binormal, worldView)).xyz; float3 vTangent = normalize(mul(i.tangent, worldView)).xyz; float3 vNormal = normalize(mul(i.normal, worldView)).xyz; #endif o.vBinormal = vBinormal; o.vTangent = vTangent; o.vNormal = vNormal; return o; }; PS_INPUT vs_main_uv2(BUMPED_VERTEX_FORMAT i) { PS_INPUT o=(PS_INPUT)0; PROJECT_POSITION( o.pos ) o.tc = i.tc; o.tc2 = i.tc2; o.wPos = worldPos.xyz; o.vPos = mul(float4(worldPos.xyz, 1.0f), g_viewMat); // // // #if SKINNED CALCULATE_TS_MATRIX float3 vBinormal = normalize(mul(tsMatrix[1], g_viewMat)).xyz; float3 vTangent = normalize(mul(tsMatrix[0], g_viewMat)).xyz; float3 vNormal = normalize(mul(tsMatrix[2], g_viewMat)).xyz; #else float3 vBinormal = normalize(mul(i.binormal, worldView)).xyz; float3 vTangent = normalize(mul(i.tangent, worldView)).xyz; float3 vNormal = normalize(mul(i.normal, worldView)).xyz; #endif o.vBinormal = vBinormal; o.vTangent = vTangent; o.vNormal = vNormal; return o; }; float4 ps_main(PS_INPUT i, uniform bool useUV2, uniform bool reflection, uniform bool lighting, uniform bool normalmapping, float face : VFACE) : COLOR0 { // // albedo // float4 albedo = tex2D(diffuseSampler, i.tc); #ifndef AIRCRAFT_OBJECT float4 camuflageMap = tex2D( camuflageSampler, i.tc ); float4 decals = 0; if(useUV2) { decals = tex2D( decalSampler, i.tc2.xy ) * max( face, 0.0 ); } albedo.rgb = lerp( lerp( camuflageMap.rgb, decals.rgb, decals.w ), albedo.rgb, albedo.w ); #else albedo.rgb = lerp( bottomColor.rgb, albedo.rgb, albedo.w); #endif // else // { // decals = 0; // } albedo = gamma_to_linear_4(albedo); // // TBN // float3 vTangent = normalize(i.vTangent); float3 vBinormal = normalize(i.vBinormal); float3 vNormal = normalize(i.vNormal); // // normal // if( normalmapping ) { float2 normalMapValue = tex2D( normalSampler, i.tc ).xy; normalMapValue.xy = normalMapValue.xy * (255.0 / 256.0) * 2.0 - 1.0; // 128 - normalmap zero value float3 tNormal = normalize(float3(normalMapValue.xy, 1.0)); tNormal = lerp(float3(0, 0, 1.0), tNormal, normalmap_weight); vNormal = float3( dot(tNormal, float3(vTangent.x, vBinormal.x, vNormal.x)), dot(tNormal, float3(vTangent.y, vBinormal.y, vNormal.y)), dot(tNormal, float3(vTangent.z, vBinormal.z, vNormal.z))); vNormal = normalize( vNormal ); } float3 wNormal = normalize(mul(float4(vNormal, 0), g_invViewMat).xyz); // // view vectors // float3 wViewVec = i.wPos - g_cameraPos; float3 vViewVec = normalize(i.vPos); float dist = length(wViewVec); wViewVec /= dist; // // fresnel term // float fresnelExp_ = 5.0; float fresnelConstant_ = 0.04; float fresnel_out = fresnel(-vViewVec, vNormal, fresnelExp_, fresnelConstant_); //TODO //float fresnel_in = fresnel(i.vLightVec.xyz, vNormal, fresnelExp, fresnelConstant); // // shadowmapping // #ifndef AIRCRAFT_OBJECT #ifdef AIRCRAFT_NO_SELFSHADOW float shadowing = 1; #else float shadowing = tex2D(selfShadowSampler, i.tc).a; #endif #else float shadowing = 1; #endif // // lighting // //materialProps - x - specular multiplier, y - glossiness (specular power), z - alpha test value, w - nonmetal parameter float4 materialProps = tex2D(specularPowerSampler, i.tc); float glossiness = materialProps.y; float glossiness_corrected = glossiness; if (glossinessOffset > 0) { glossiness_corrected = lerp(glossiness, 1.0, glossinessOffset); } else { glossiness_corrected = lerp(0, glossiness, 1.0 + glossinessOffset); } glossiness = lerp(glossiness_corrected, glossiness, albedo.w); glossiness = (gloss_const_enabled) ? gloss_const : glossiness; /* float ags = 0.9 * abs(glossiness_shift); // float glossiness_shift_power = pow(2, 2.0 * -sign(glossiness_shift) * ags / (1.0 - ags)); float glossiness_shift_power = exp(-sign(glossiness_shift) * ags / (1.0 - ags)); float gloss_remap_val = 0.7; // remap texture range glossiness = pow(glossiness, gloss_remap_val * glossiness_shift_power); */ glossiness = glossiness * 0.9999 + 0.0001; /* { float gloss_remap_val = 0.7; // remap texture range glossiness = pow(glossiness, gloss_remap_val); } */ // remap gloss texture { float gloss_remap = 0.2; float a = sqrt(0.25 + 1 / gloss_remap); glossiness = -1.0 / (gloss_remap * (glossiness + a - 0.5)) + a + 0.5; } // float specular_absorbtion = pow(glossiness, 0.5); // float specular_absorbtion = 1.0 - pow(1.0 - glossiness, 4); float NdotV = dot(wNormal, -wViewVec); // float specular_absorbtion = 1.0 - pow(1.0 - glossiness, 2.0 + 2.0 * NdotL); float invgloss = 1.0 - glossiness; float invgloss2 = invgloss * invgloss; float invgloss4 = invgloss2 * invgloss2; float invgloss8 = invgloss4 * invgloss4; float specular_absorbtion = 1.0 - lerp(invgloss2, invgloss8, NdotV); // // metalliness // // float nonmetal = camuflageMap.a * materialProps.w; #if !defined(AIRCRAFT_OBJECT) float nonmetal = (1.0 - (1.0 - camuflageMap.a) * (1.0 - decals.w)) * materialProps.w; #else // float nonmetal = materialProps.w * bottomColor.a; float nonmetal = materialProps.w * lerp(bottomColor.a, 1.0, albedo.w); #endif // nonmetal = gamma_to_linear_1(nonmetal); // float4 fresnel_complex = lerp(albedo, fresnel_out, nonmetal); // metal color defined by diffuse textures // float4 fresnel_complex = lerp(1.0, fresnel_out * specular_absorbtion, nonmetal); // metal color is 1 float4 fresnel_complex = lerp(float4(materialSpecular.xyz, 1.0), fresnel_out * specular_absorbtion, nonmetal); // metal color defined by material specular color // // lighting // float3 diffuse = 0; float3 specular = 0; if(lighting) { for (int light = 0; light < nPointLights; light++) { float3 wL = normalize( pointLights[light].position - i.wPos ); float distance = dot( pointLights[light].position - i.wPos, wL ); float attenuation = saturate((-distance + pointLights[light].attenuation.x) * pointLights[light].attenuation.y); float fresnel_in = fresnel(wL, wNormal, fresnelExp_, fresnelConstant_); attenuation *= blinn_phong_mod( wNormal, -wViewVec, normalize(pointLights[light].position - i.wPos), glossiness ).x; diffuse += pointLights[light].colour.rgb * attenuation * (1.0 - fresnel_in * specular_absorbtion); } for (int light = 0; light < nSpecularPointLights; light++) { float3 wL = normalize( specularPointLights[light].position - i.wPos ); float distance = dot( specularPointLights[light].position - i.wPos, wL ); float attenuation = saturate((-distance + specularPointLights[light].attenuation.x) * specularPointLights[light].attenuation.y); float fresnel_in = fresnel(wL, wNormal, fresnelExp_, fresnelConstant_); attenuation *= blinn_phong_mod( wNormal, -wViewVec, normalize(specularPointLights[light].position - i.wPos), glossiness ).y; specular += specularPointLights[light].colour.rgb * attenuation; } for (int light = 0; light < nSpotLights; light++) { float3 wL = normalize( spotLights[light].position - i.wPos ); float distance = dot( spotLights[light].position - i.wPos, wL ); float fresnel_in = fresnel(wL, wNormal, fresnelExp_, fresnelConstant_); float attenuation = ((-distance + spotLights[light].attenuation.x) * spotLights[light].attenuation.y) * //distance attenuation (dot( -spotLights[light].direction, wL ) -spotLights[light].attenuation.z) / (1.0 - spotLights[light].attenuation.z); //cone angle attenuation attenuation = saturate(attenuation); float4 lightLevels = blinn_phong_mod( wNormal, -wViewVec, normalize(spotLights[light].position - i.wPos), glossiness ); lightLevels *= attenuation; lightLevels.x *= (1.0 - fresnel_in * specular_absorbtion); diffuse += spotLights[light].colour.rgb * lightLevels.x; specular += spotLights[light].colour.rgb * lightLevels.y; } } // // cubemap // float4 reflectionColour = 0; if(reflection) { float3 wReflVec = reflect(wViewVec, wNormal); wReflVec = lerp(wReflVec, wNormal, invgloss8); // reflectionColour = texCUBElod(reflectionCubeSampler, float4(wReflVec, (1.0 - glossiness) * 7.0)); // reflectionColour = texCUBElod(reflectionCubeSampler, float4(wReflVec, pow((1.0 - glossiness), 1.2) * 6.0)); // reflectionColour = texCUBElod(reflectionCubeSampler, float4(wReflVec, pow((1.0 - glossiness), 1) * 4.0)); reflectionColour = texCUBElod(reflectionCubeSampler, float4(wReflVec, (1.0 - glossiness) * 6.0)); // reflectionColour.rgb = color_saturation(reflectionColour.rgb, cubemap_saturation); } //specular float reflectionMask = materialProps.x; //add reflection specular += reflectionColour.rgb; // // combine everything // float3 ambient = nonmetal * ambientColour * albedo.rgb; // TODO leave just arrived ambient light if(reflection) { // ambient = texCUBElod(reflectionCubeSampler, float4(wNormal, 5.0)) * nonmetal * albedo.rgb; // ambient = color_saturation(texCUBElod(reflectionCubeSampler, float4(wNormal, 5.0)), cubemap_saturation) * nonmetal * albedo.rgb; ambient = texCUBElod(reflectionCubeSampler, float4(wNormal, 5.0)) * nonmetal * albedo.rgb; } // float4 colour = float4( (nonmetal * albedo.rgb * diffuse + specular.rgb * reflectionMask * fresnel_complex/* * reflectionAmount*/) * shadowing + ambient, albedo.w); float4 colour = float4((nonmetal * albedo.rgb * diffuse + specular.rgb * reflectionMask * fresnel_complex) * shadowing + ambient, albedo.w); float3 fogColour = skyDomeColor(skyDomeSampler, wViewVec, -directionalLights[0].direction); float fog = opticalDepth(dist); colour.rgb = lerp(colour.rgb, fogColour, fog); #ifdef DAMAGE_TEXTURE //make holes colour.a = materialProps.z; #endif return pack_hdr_value(colour); }; #ifndef AIRCRAFT_OBJECT technique AircraftHangarHigh < bool dualUV = true; #if SKINNED bool skinned = true; #endif > { pass Pass_0 { #ifdef DAMAGE_TEXTURE ALPHATESTENABLE = TRUE; ALPHAREF = 128;//TODO REMOVE THIS( must be removed in all materials ) #else ALPHATESTENABLE = FALSE; #endif ZENABLE = TRUE; ZWRITEENABLE = TRUE; ALPHABLENDENABLE = FALSE; BW_FOG FOGENABLE = TRUE; FOGTABLEMODE = NONE; FOGVERTEXMODE = LINEAR; CULLMODE = None; VertexShader = compile vs_3_0 vs_main_uv2(); PixelShader = compile ps_3_0 ps_main(true,true,true,true); } } #endif technique AircraftHangarHigh_UV2_fallback < string link_fallback = "AircraftHangarHigh"; #if SKINNED bool skinned = true; #endif > { pass Pass_0 { #ifdef DAMAGE_TEXTURE ALPHATESTENABLE = TRUE; ALPHAREF = 128;//TODO REMOVE THIS( must be removed in all materials ) #else ALPHATESTENABLE = FALSE; #endif ZENABLE = TRUE; ZWRITEENABLE = TRUE; ALPHABLENDENABLE = FALSE; BW_FOG FOGENABLE = TRUE; FOGTABLEMODE = NONE; FOGVERTEXMODE = LINEAR; CULLMODE = None; VertexShader = compile vs_3_0 vs_main_uv1(); PixelShader = compile ps_3_0 ps_main(false,true,true,true); } } shaders.zip
  8. Нет, это либо какой-то расснихрон, либо древний клиент салолётиков так и работал в конце альфы. Не знаю я, ещё и реализация спидометра у картошки на C написана, не подсмотреть А вот в 1.7.5 всё наоборот, высотомер работает, а спидометр совсем RIP. Возможно позицию все же стоит обновлять через avatarUpdate*, а не через detailedPosition().
  9. @Dragon armor ты когда-то спрашивал про физические движки. Если когда-нибудь вернешься к этой теме - посмотри в сторону pybullet/bullet3. Террейн подгрузить можно, есть визуализатор, возможность из одного процесса запустить несколько инстансов. Набор joint'ов тоже достаточен. p.s. несовпадение высоты террейна и дыры между чанками это моя лень, а не движок
  10. Там всё равно довольно древняя реализация сетевого протокола, мало чем поможет.
  11. /** * This class is used to pack a yaw, pitch and roll value for network * transmission. * * @ingroup network */ class YawPitchRoll { ... private: uint8 yaw_; uint8 pitch_; uint8 roll_; }; inline BinaryIStream& operator>>( BinaryIStream &is, YawPitchRoll &ypr ) { return is >> ypr.yaw_ >> ypr.pitch_ >> ypr.roll_; } Я на какой-то другой YawPitchRoll смотрю? UPD 21.12: yaw pitch roll - 11 бит + 10 бит + 11 бит, первый бит в каждой группе - знак (x - math.pi). xzy - 19 бит + 19 бит + 18 бит = 56 бит/7 байт, первый бит в каждой группе - знак (-1 ^ bit * x) У y первые 4 бита после знака - экспонента, остальные - мантисса. К значению всегда прибавляется константа 2.0. Как запакованы XZ понять не удалось. UPD 30.12. В общем-то координаты и направление распакованы, демка транслирующая состояние боя на соседний экран написана. Дальшейшее уже допиливание мелочей (PIGGIBACKS, пересылка пакетов, whatever). Пожалуй на этом я и остановлюсь, думаю уже можно записать в копилку виртуальную ачивку и пойти писать очреедную статью на хабр "разбор протокола wot" :P
  12. Привел было немного в чувство весь код написанный раньше и попытался разобраться с форматом avatarUpdate. Подопытным был выбран avatarUpdateAliasFullPosYawPitchRoll. Он же в виде макроса в старых исходниках BW: AVUPMSG( Alias, FullPos, YawPitchRoll ) Примеры пакетов: 2dfa78ca6f22c200009a600000 2df377be7edad000105d400000 2df977f11edf9200039aa003fd 2def79daaf3cf4000052000000 2df6790a7ee1b000002b600001 Разочарование первое: в исходниках FullPos занимает 5 байт, YawPitchRoll - 3, ещё один байт уходит на Alias (итого 9), но в трафике 12 байт. Разочарование второе: поменялся формат хранения YawPitchRoll. В исходниках это три байта указывающих на три угла, но в игровом клиенте используются 4 байта. Первый с конца - Roll. # aa0000XX # 0, 32, 64, 96, 128, 160, 192, 224, 0 # XX=0 'yaw': -2.11075758934021, 'pitch': 0.0, 'roll': 0.0 # XX=192 'yaw': -2.11075758934021, 'pitch': 0.0, 'roll': 1.1780972480773926 # XX=224 'yaw': -2.11075758934021, 'pitch': 0.0, 'roll': 1.3744468688964844 # roll = XX / 256 * (math.pi / 2) Четвертый с конца - Yaw. # XX000000 by 16 # XX=0 'yaw': 0.0, 'pitch': 0.0, 'roll': 0.0 # XX=16 'yaw': 0.39269909262657166, 'pitch': 0.0, 'roll': 0.0 # XX=128 'yaw': -3.1415927410125732, 'pitch': 0.0, 'roll': 0.0 Второй и третий с конца байты указывают на pitch, инвертируют его и немного влияют на yaw и roll. # aaXXXX00 # XX=0 'yaw': -2.11075758934021, 'pitch': 0.0, 'roll': 0.0 # XX=16 'yaw': -2.11075758934021, 'pitch': -1.5661900043487549, 'roll': 0.0 # XX=32 'yaw': -2.107689619064331, 'pitch': 0.012283843010663986, 'roll': 0.0 # XX=48 'yaw': -2.107689619064331, 'pitch': -1.5539060831069946, 'roll': 0.0 # XX=64 'yaw': -2.104621648788452, 'pitch': 0.024567686021327972, 'roll': 0.0 # XX=80 'yaw': -2.104621648788452, 'pitch': -1.541622281074524, 'roll': 0.0 # XX=96 'yaw': -2.1015536785125732, 'pitch': 0.03685152903199196, 'roll': 0.0 # XX=112 'yaw': -2.1015536785125732, 'pitch': -1.5293384790420532, 'roll': 0.0 # XX=128 'yaw': -2.0984857082366943, 'pitch': 0.049135372042655945, 'roll': 0.0 Разочарование третье: формат позиции тоже новый, 7 байт вместо 5. Меняя значение одного последнего байта меняется Z. Особенности: меняется не от ноля, на разных картах координата пересчитывается в разные значения (возможно зависит от размера карты). # XX in range(0, 255, step=16), all other bytes fixed # 'x': 67.27529907226562, 'y': 509.96875, 'z': -459.12945556640625 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -474.75543212890625 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -490.3813781738281 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -506.00732421875 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -522.2589111328125 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -553.5108642578125 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -584.7627563476562 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -616.0146484375 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -648.517822265625 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -711.0216674804688 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -773.5255126953125 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -836.029296875 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -901.0357055664062 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -1026.0433349609375 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -1151.051025390625 # 'x': 67.27529907226562, 'y': 509.96875, 'z': -1276.05859375 Если кто-нибудь встречал уже эти форматы (например, где-нибудь в конфигах карт) - напишите.
  13. Неа, не больше. Точно. Посмотрел уже, exposed индексы в клиенте назначаются вплоть до 0x5b (dec=91). В ангаре сообщение a1 всегда variable-len (с заголовком размера) и совершенно разными payload. В примере выше я приводил пример когда оно содержит 1 и 6 байт, но так же есть вот такие случаи когда в payload прилетает pickle + zlib следующего содержания: {'progress': {'lootedStages': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'currentStage': 5, 'daysLeft': 9}, 'params': {'extraReward': [('Add', {'count': 750, 'type': 16})], 'duration': 30.0, 'stages': {1: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 2: {'rewards': [('Add', {'count': 750, 'type': 16})]}, 3: {'rewards': [('Add', {'count': 750, 'type': 16})]}, 4: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL004_Lucky'})]}, 5: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 6: {'rewards': [('Add', {'count': 750, 'type': 16})]}, 7: {'rewards': [('Add', {'count': 400, 'type': 6})]}, 8: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL002_Signals'})]}, 9: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 10: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 11: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 12: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL001_Credits'})]}, 13: {'rewards': [('Add', {'count': 50000, 'type': 0})]}, 14: {'rewards': [('Add', {'count': 400, 'type': 6})]}, 15: {'rewards': [('Add', {'count': 400, 'type': 6})]}, 16: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL034_Resourses'})]}, 17: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL004_Lucky'})]}, 18: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL002_Signals'})]}, 19: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL001_Credits'})]}, 20: {'rewards': [('Lootbox', {'count': 1, 'ignoreEpic': 1, 'boxType': 'PCL034_Resourses'})]}, 21: {'rewards': [('Add', {'count': 1500, 'type': 16})]}, 22: {'rewards': [('Add', {'count': 100, 'type': 1})]}, 23: {'rewards': [('Add', {'count': 1, 'type': 23})]}, 24: {'rewards': [('Lootbox', {'count': 1, 'boxType': 'PCL005_Epic'})]}}, 'id': 2211, 'background': 'blue'}, 'currentStage': 8} Никакие методы при этом у entity не вызываются, property с таким форматом тоже нет. Склоняюсь к тому что это уже какое-то современное ноу-хау картошки и смотреть реализацию нужно будет в клиенте игры. Пока что только собираю статистику по сообщениям этого формата, парсингу они не мешают т.к. размер данных записан в само сообщение. Вот всё что мне попадалось в одной из сессий в ангаре (чистые данные без заголовка a1 + payload len). Запишу чуть позже ещё сессию боя и может вопрос прояснится даже без копания в ассемблере. 03ffab0200780185d4d9521341140660b2872460d871df356ec8ea2e8288a8932802ed1ee324d38448c8e474cf08b9e82aafbcf61d7c145fc367f0193c27f64c4daa42257753f9ce3ffdf7ccf4f7b082508e259bc2ae0a2e25e07524c73275db76b8b5e998552e215a8458ce08196123c259a6e20ac11b4efb3f881b5196b4cc96ccf36d071246ca65f1a629cc3d094905fd3996e6078e3037f8be292c481521cd22cb96a5209363b18aed369cc2df308b3aad2637b2ee0f183031ce15a653b31b30b8b6b4d8d7feb1b8fcbf94230ab2b81405432c21daa112868b30a25347fdd4f5df3ab50f53c74c6960b1f11da4139a4efab46301479146141c237a5cd313dde949a45105a7889e66893c6e59d93e5070c6e34688a56ad5862df86ab356c1ab04febf855559667d253f3d3d5fcabb95dd169cc5259ec3b09882f3147641dff7a21754e8687309695cc165a2394daff8b4a3cd55a40905d7885ed7f4864f7f86f41ec571015348f191dd243a1d6833e3f1c3db0cb6dbcc9636b1ac5997308b717318d7af609ee216f49d6f79519d7d6e234d29b843f4aea6f7bad3fb48d30a1e107da8e96277fa086946c112d1e5409fc71eefd567a6b422b8557324ac609f271837a06095e29eea3baf79519d7d9e211d54f09ce80b4d0d9f766c7a1e29bed205a22f357dd59dae23cd2a784d7423d067d3e387f7c9d2f3999b2f6d7069bb42e217bd858d18060e297843816f0381ef7a06eed00bfb1ec787157ca0f18f81f14fbdc7e9fd28e2f88882cf345e0a8c7fe93d4e8fc3c4f15105651aaf04c6addee3d49de3f898826d1aafea7ddff1460b7f628113a986745cc157a2bb9ad63d6a585a8630740fe5848206495bcba62fbd6f6d0225a09c542048cac0ea9d80f6cf8a74fbeb5a28d119022e4e7f33a5cbc2350bf60bbf922c55362bbb558147a905072c5aaebb1c5aae3bf50f00c0f71b 09 12 110493c2c2c2
  14. Эти магические номера методов это что-то что мой мозг отказывается понимать, даже после прочтения кода отосящегося к subslots. Залез в клиент через python shell, поставил трейс на вызовы любых методов у Account entity. Что происходит в клиенте: ('onGetPortsInfo', (PlayerAccount at 0x000001D82E0086D8, 'x\x9c%\x8d\xbdR\x83@\x14Fc\x08\x10b\xa2FM\xfc\xb7\xa6\xca\x8c\x9d\xcf\x9046\xb7d\xc6\x0bl\xd8\x15\xd8\xe5\xde]d\xb0\xb2K\xedS\xf82\x16>\x92\xcc\xd8\x9dsf\xbe\xf9>\xc7\t\x1d\xc5\t\x8dc\xf0S\xb4*#\x0f\xc2\x86E\xad\xda\x9a&\xe0\x9bL\xa0&\x1f<\xdb\xa4\x14@P\x19\x9d\x1bM!x\xd2\xeei\n\xa1\x16]o\xb8\xa4\x08\xbc\x9c{\x9aA\x98\xb7\xbaTC9\x86\xa8F\xb6BU\x95\xa09\x84\x12\xeb\xb4\xe5\x82\x16\x10\x95l\xb4u\x98;:\x81E&\x95F\xe4F\x14\x852t\n\xbe\xc3tX\x9c\x81\xaf\x1cV=-!\xd8\xbf\x19\xce-\x9d\xc3\\\x9bw\xc3\xc6Z\xd5\xdb\x92.`R\xb6,\xe8\x12\x02\xd7)\x97IZ\xc1\x14?Z\xaeP\x0bZC\x88\r\xab\xea\xe9\x99\xae b\xe3\x9c\xe0\x1ck\xba\x06\x8f\x87\xa3\x1b\x91\xd0m,W\xbb\xd1nt\xa0;\xb9\xfe\x87{\xe9o\x7f\xbf_\xb3\xed\xcf\xa2\xcb\x0e\xf4 g\xdb\x97e7h\xf95\xe8\xa3\x90\x9e\xd8\xfc\x01\xed\xeeg?'), {}) ('updateBalanceStatus', (PlayerAccount at 0x000001D82E0086D8, 1), {}) ('onCheckGamePing', (PlayerAccount at 0x000001D82E0086D8, 45570L), {}) В этот же момент в сообщениях: # 0x7e - 0x44 == 0x3a == onGetPortsInfo ([unknown: <Blob>]) # 7eff12010000789c258dbd528340144663081062a2464dfcb7a6ca8c9dcf903436b764c60b6cd815d8e5de5d64b0b24bed53f832163e92ccd89d7366bef93ec7091dc5098d63f053b42a230fc28645adda9a26e09b4ca0261f3cdba4144050199d1b4d2178d2ee690aa1165d6fb8a408bc9c7b9a4198b7ba54433986a846b6425595a0398412ebb4e5821610956cb475983b3a8145269546e446148532740abec374589c81af1c563d2d21d8bf19ce2d9dc35c9b77c3c65ad5db922e6052b62ce81202d72997495ac1143f5aae500b5a43880dabeae999ae2062e39ce01c6bba068f87a31b91d06d2c57bbd16e74a03bb9fe877be96f7fbf5fb3edcfa2cb0ef42067db97653768f935e8a3909ed8fc01edee673fff0e0100 # selectPlayerEntity # 1a # ?? # a0 # selectPlayerEntity # 1a # ?? # a10109 # selectPlayerEntity # 1a # ?? # a10112 # selectPlayerEntity # 1a # 0x50 - 0x44 == 0x0c == updateBalanceStatus ([unknown: <UInt8>]) # 5001 # selectPlayerEntity # 1a # ?? # a106110493c2c2c2 # 0x70 - 0x44 == 0x2c == onCheckGamePing ([unknown: <UInt64>]) # 7002b2000000000000 Если на a10100, a10112, a106110493c2c2c2 можно было бы ещё подумать что они свойства, то a0 в такой формат не вписывается. Но это и не метод, никаких методов в это время не вызывалось. С другой стороны иногда 2 байт (a1*06*110493c2c2c2) обозначает длину даных, т.е. это скорее всего varible-len сообщения. p.s. у Account 92 exposed метода и 4 client-server свойства. p.p.s. 0x44 и 0xa2 в клиенте всё ещё фигурируют. в asm видно что клиент заполняет entityMethod hander'ом структурку, где хандлеру соответсвуют индексы от 0x44 до 0xa2. 00E44FE0 Call to WorldOfWarships32.00E44FE0 from WorldOfWarships32.00A8D453 ; registerMessage 02336078 Arg1 = ASCII "updateEntity" 00000001 Arg2 = 1 00000002 Arg3 = 2 027B75A8 Arg4 = WorldOfWarships32.27B75A8 00E44FF9 INT3: AL = 43 (67.) 00E44FE0 Call to WorldOfWarships32.00E44FE0 from WorldOfWarships32.00A8D493 ; registerMessage 02336068 Arg1 = ASCII "entityMethod" 00000002 Arg2 = 2 00000000 Arg3 = 0 027B75D8 Arg4 = WorldOfWarships32.27B75D8 00E44FF9 INT3: AL = 44 (68.) 00E44FE0 Call to WorldOfWarships32.00E44FE0 from WorldOfWarships32.00A8D503 ; registerMessage 02336058 Arg1 = ASCII "entityProperty" 00000002 Arg2 = 2 00000000 Arg3 = 0 027B75F0 Arg4 = WorldOfWarships32.27B75F0 00E44FF9 INT3: AL = 0A2 (162.) Надо взять неделюку отдыха и вернуться уже со свежей головой и ассемблером. Если вдруг кого-то из читающих осенит - не молчите =)
×
×
  • Create New...