mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-03-23 14:21:01 +00:00
1 line
No EOL
14 KiB
JavaScript
1 line
No EOL
14 KiB
JavaScript
import"./logger-CC5j_O4o.js";import{A as e,D as t,O as n,_ as r,a as i,b as a,d as o,l as s,n as c,r as l,t as u,v as d,y as f}from"./streamHelpers-CgcDlqe5.js";import{i as p}from"./scene-OlUAvaR5.js";import{x as m}from"./index-KOH_0HDb.js";function h(e){let t=null,n=null,i=null,a=null,o=null,s=null,c=NaN,l=null;for(let u=0;u<e.length;u++){let d=e[u].split(` `);if(d.length>=3&&d[1]?.endsWith(`Game`)&&(i=d[1]),e[u]!==`readplayerinfo`)continue;let f=e[u+1];if(f){if(f.startsWith(`1 `)){let e=f.split(` `);e[1]&&(c=parseInt(e[1],10)),e[2]&&(s=r(e[2]).trim());continue}if(f.startsWith(`2 `)){let e=f.split(` `);e[1]&&(a=e[1]),e[3]&&(l=e[3]),e[4]&&(t=e[4]);continue}if(f.startsWith(`3 `)){let e=f.split(` `);e[1]&&(o=e[1]),e[2]&&(n=e[2])}}}return{missionDisplayName:t,missionType:n,gameClassName:i,serverDisplayName:a,mod:o,recorderName:s,recorderClientId:Number.isFinite(c)?c:null,recordingDate:l}}function g(e){let t={weaponsHud:null,backpackHud:null,inventoryHud:null,teamScores:[],playerRoster:new Map,chatMessages:[],clockTimeMin:null,gravity:-20};if(!e.length)return t;let n=0,i=()=>{let t=e[n++];return t===`<BLANK>`?``:t??``};if(i(),n>=e.length)return t;let a=parseInt(i(),10)||0,o=new Map;for(let e=0;e<a;e++){let e=i().split(` `),n=r(e[0]??``).trim(),a=parseInt(e[2],10),s=parseInt(e[4],10),c=parseInt(e[5],10)||0,l=parseInt(e[6],10)||0,u=parseInt(e[7],10)||0;!isNaN(a)&&!isNaN(s)&&t.playerRoster.set(a,{name:n,teamId:s,score:c,ping:l,packetLoss:u}),!isNaN(s)&&s>0&&o.set(s,(o.get(s)??0)+1)}if(n>=e.length||(i(),n>=e.length))return t;{let e=i().split(` `),n=e[0]??``,r=e[1]===`1`||e[1]===`true`,a=e[2]??``,o=e[4]===`1`||e[4]===`true`;r&&n&&(t.backpackHud={packIndex:c(n),active:o,text:a})}if(n>=e.length)return t;let s=i().split(` `),l=parseInt(s[4],10)||0,u=parseInt(s[5],10)||0,d=parseInt(s[6],10);for(let e=0;e<l;e++)i();let f=new Map;for(let e=0;e<u;e++){let e=i().split(` `),t=parseInt(e[0],10),n=parseInt(e[1],10);isNaN(t)||f.set(t,isNaN(n)?-1:n)}if(t.weaponsHud={slots:f,activeIndex:isNaN(d)?-1:d},n>=e.length)return t;let p=i().split(` `),m=parseInt(p[4],10)||0,h=parseInt(p[5],10)||0,g=parseInt(p[6],10);for(let e=0;e<m;e++)i();{let e=new Map;for(let t=0;t<h;t++){let t=i().split(` `),n=parseInt(t[0],10),r=parseInt(t[1],10);!isNaN(n)&&!isNaN(r)&&r>0&&e.set(n,r)}e.size>0&&(t.inventoryHud={slots:e,activeSlot:isNaN(g)?-1:g})}if(n>=e.length)return t;let _=i().split(` `),v=_[1]??``,y=parseInt(_[2],10)||0,b=[];for(let e=0;e<y;e++)b.push(i());if(v===`CTFGame`&&y>=8)for(let e=0;e<2;e++){let n=e*4,r=e+1;t.teamScores.push({teamId:r,name:b[n]??``,score:parseInt(b[n+1],10)||0,playerCount:o.get(r)??0})}else if(v===`TR2Game`&&y>=4)for(let e=0;e<2;e++){let n=e*2,r=e+1;t.teamScores.push({teamId:r,name:b[n+1]??``,score:parseInt(b[n],10)||0,playerCount:o.get(r)??0})}if(n>=e.length)return t;{let e=i().split(` `),n=parseFloat(e[1]??``);Number.isFinite(n)&&(t.clockTimeMin=n)}for(let r=0;r<10&&!(n>=e.length);r++){let e=i();e&&t.chatMessages.push(e)}if(n<e.length){let e=parseFloat(i());Number.isFinite(e)&&(t.gravity=e)}return t}var _=class extends m{parser;initialBlock;moveTicks=0;absoluteYaw=0;absolutePitch=0;lastAbsYaw=0;lastAbsPitch=0;exhausted=!1;_teamScoresGen=0;_rosterGen=0;_weaponsHudGen=0;_inventoryHudGen=0;_cachedSnapshot=null;_cachedSnapshotTick=-1;_snap=null;constructor(e){super(),this.parser=e,this.registry=e.getRegistry(),this.ghostTracker=e.getGhostTracker();let t=e.initialBlock;this.initialBlock={dataBlocks:t.dataBlocks,initialGhosts:t.initialGhosts,controlObjectGhostIndex:t.controlObjectGhostIndex,controlObjectData:t.controlObjectData,targetEntries:t.targetEntries,sensorGroupColors:t.sensorGroupColors,taggedStrings:t.taggedStrings,initialEvents:t.initialEvents,demoValues:t.demoValues,firstPerson:t.firstPerson},this.reset()}getDataBlockData(e){let t=this.initialBlock.dataBlocks.get(e);return t?.data?t.data:this.parser.getPacketParser().dataBlockDataMap?.get(e)}_shapeConstructorCache=null;getShapeConstructorSequences(e){if(!this._shapeConstructorCache){this._shapeConstructorCache=new Map;for(let[,e]of this.initialBlock.dataBlocks){if(e.className!==`TSShapeConstructor`||!e.data)continue;let t=e.data.shape,n=e.data.sequences;t&&n&&this._shapeConstructorCache.set(t.toLowerCase(),n)}}return this._shapeConstructorCache.get(e.toLowerCase())}getTimeSec(){return this.moveTicks*(32/1e3)}getCameraYawPitch(e){let t=this.lastControlType===`player`,n=t?this.absoluteYaw:this.lastAbsYaw,r=t?this.absolutePitch:this.lastAbsPitch;return t&&(this.lastAbsYaw=n,this.lastAbsPitch=r),{yaw:n,pitch:r}}getControlPlayerHeadPitch(e){return l(this.absolutePitch/u,-1,1)}onTeamScoresChanged(){this._teamScoresGen++}onRosterChanged(){this._rosterGen++}onWeaponsHudChanged(){this._weaponsHudGen++}onInventoryHudChanged(){this._inventoryHudGen++}reset(){this.parser.reset(),this.ghostTracker=this.parser.getGhostTracker(),this._cachedSnapshot=null,this._cachedSnapshotTick=-1,this._snap=null,this.resetSharedState();for(let[e,t]of this.initialBlock.taggedStrings)this.netStrings.set(e,t);for(let e of this.initialBlock.targetEntries)e.name&&this.targetNames.set(e.targetId,r(e.name).trim()),this.targetTeams.set(e.targetId,e.sensorGroup),this.targetRenderFlags.set(e.targetId,e.targetData);for(let e of this.initialBlock.sensorGroupColors){let t=this.sensorGroupColors.get(e.group);t||(t=new Map,this.sensorGroupColors.set(e.group,t)),t.set(e.targetGroup,{r:e.r,g:e.g,b:e.b})}if(this.moveTicks=0,this.absoluteYaw=0,this.absolutePitch=0,this.lastAbsYaw=0,this.lastAbsPitch=0,this.firstPerson=this.initialBlock.firstPerson,this.lastControlType=i(this.initialBlock.controlObjectData)??`player`,this.isPiloting=this.lastControlType===`player`?!!(this.initialBlock.controlObjectData?.pilot||this.initialBlock.controlObjectData?.controlObjectGhost!=null):!1,this.lastPilotGhostIndex=this.isPiloting&&typeof this.initialBlock.controlObjectData?.controlObjectGhost==`number`?this.initialBlock.controlObjectData.controlObjectGhost:void 0,this.isPiloting){let e=this.initialBlock.controlObjectData?.controlObjectData?.angPosition;if(e&&typeof e.w==`number`){this.lastVehicleHeading=d(e),this.lastVehiclePitch=f(e);let t=a(e);if(t){let[e,n,r,i]=t,a=1-2*(n*n+r*r),o=2*(e*n+r*i),s=2*(e*r-n*i);this.lastVehicleOrbitDir=[-a,-o,-s]}}}if(this.lastCameraMode=this.lastControlType===`camera`&&typeof this.initialBlock.controlObjectData?.cameraMode==`number`?this.initialBlock.controlObjectData.cameraMode:void 0,this.lastOrbitGhostIndex=this.lastControlType===`camera`&&typeof this.initialBlock.controlObjectData?.orbitObjectGhostIndex==`number`?this.initialBlock.controlObjectData.orbitObjectGhostIndex:void 0,this.lastControlType===`camera`){let e=this.initialBlock.controlObjectData?.minOrbitDist,t=this.initialBlock.controlObjectData?.maxOrbitDist,n=this.initialBlock.controlObjectData?.curOrbitDist;typeof e==`number`&&typeof t==`number`&&Number.isFinite(e)&&Number.isFinite(t)?this.lastOrbitDistance=Math.max(0,t-e):typeof n==`number`&&Number.isFinite(n)?this.lastOrbitDistance=Math.max(0,n):this.lastOrbitDistance=void 0}else this.lastOrbitDistance=void 0;let e=this.getAbsoluteRotation(this.initialBlock.controlObjectData);e&&(this.absoluteYaw=e.yaw,this.absolutePitch=e.pitch,this.lastAbsYaw=e.yaw,this.lastAbsPitch=e.pitch),this.exhausted=!1,this.latestFov=100,this.latestControl={ghostIndex:this.initialBlock.controlObjectGhostIndex,data:this.initialBlock.controlObjectData,position:s(this.initialBlock.controlObjectData?.position)?this.initialBlock.controlObjectData?.position:void 0},this.controlPlayerGhostId=this.lastControlType===`player`&&this.initialBlock.controlObjectGhostIndex>=0?t(`Player`,this.initialBlock.controlObjectGhostIndex):void 0;for(let e of this.initialBlock.initialGhosts){if(e.type!==`create`||e.classId==null)continue;let r=this.registry.getGhostParser(e.classId)?.name;if(!r)throw Error(`No ghost parser for classId ${e.classId} (ghost index ${e.index})`);let i=t(r,e.index),a={id:i,ghostIndex:e.index,className:r,spawnTick:0,type:n(r),rotation:[0,0,0,1]};if(this.applyGhostData(a,e.parsedData),e.parsedData){let t=p(r,e.index,e.parsedData);t&&(a.sceneData=t)}this.entities.set(i,a),this.entityIdByGhostIndex.set(e.index,i)}if(this.playerSensorGroup===0&&this.lastControlType===`player`&&this.latestControl.ghostIndex>=0){let e=this.entityIdByGhostIndex.get(this.latestControl.ghostIndex),t=e?this.entities.get(e):void 0;t?.sensorGroup!=null&&t.sensorGroup>0&&(this.playerSensorGroup=t.sensorGroup)}for(let e of this.initialBlock.initialEvents){let t=this.registry.getEventParser(e.classId)?.name;if(t===`SetSensorGroupEvent`&&e.parsedData){let t=e.parsedData.sensorGroup;t!=null&&(this.playerSensorGroup=t)}else if(t===`RemoteCommandEvent`&&e.parsedData){let t=this.resolveNetString(e.parsedData.funcName),n=e.parsedData.args;t===`ServerMessage`&&this.handleServerMessage(n),this.handleHudRemoteCommand(t,n)}}let c=g(this.initialBlock.demoValues);c.weaponsHud&&(this.weaponsHud.slots=c.weaponsHud.slots,this.weaponsHud.activeIndex=c.weaponsHud.activeIndex),c.backpackHud&&(this.backpackHud.packIndex=c.backpackHud.packIndex,this.backpackHud.active=c.backpackHud.active,this.backpackHud.text=c.backpackHud.text),c.inventoryHud&&(this.inventoryHud.slots=c.inventoryHud.slots,this.inventoryHud.activeSlot=c.inventoryHud.activeSlot),this.teamScores=c.teamScores,this.playerRoster=new Map(c.playerRoster),c.clockTimeMin!=null&&(this.clockAnchorStreamSec=0,this.clockDurationMs=c.clockTimeMin*60*1e3);for(let e of c.chatMessages){let t=o(e);if(!t.length)continue;let n=t.map(e=>e.text).join(``);if(!n.trim())continue;let r=t[0].colorCode;if(t.some(e=>e.colorCode===3||e.colorCode===4)&&n.includes(`: `)){let e=n.indexOf(`: `);this.pushChatMessage({timeSec:0,sender:n.slice(0,e),text:n.slice(e+2),kind:`chat`,colorCode:r,segments:t})}else this.pushChatMessage({timeSec:0,sender:``,text:n,kind:`server`,colorCode:r,segments:t})}this.updateCameraAndHud()}getSnapshot(){if(this._cachedSnapshot&&this._cachedSnapshotTick===this.moveTicks)return this._cachedSnapshot;let e=this.buildSnapshot();return this._cachedSnapshot=e,this._cachedSnapshotTick=this.moveTicks,e}getEffectShapes(){let e=new Set,t=t=>{let n=t.dtsFileName;n&&e.add(n);let r=t.subExplosions;if(Array.isArray(r))for(let t of r){if(t==null)continue;let n=this.getDataBlockData(t);n?.dtsFileName&&e.add(n.dtsFileName)}};for(let[,e]of this.initialBlock.dataBlocks){let n=e.data?.explosion;if(n==null)continue;let r=this.getDataBlockData(n);r&&t(r)}return[...e]}stepToTime(e,t=1/0){let n=Number.isFinite(e)?Math.max(0,e):0,r=Math.floor(n*1e3/32),i=!1;r<this.moveTicks&&(this.reset(),i=!0);let a=this.exhausted,o=0;for(;!this.exhausted&&this.moveTicks<r&&o<t&&this.stepOneMoveTick();)o+=1;if(o===0&&!i&&a===this.exhausted&&this._cachedSnapshot&&this._cachedSnapshotTick===this.moveTicks)return this._cachedSnapshot;let s=this.buildSnapshot();return this._cachedSnapshot=s,this._cachedSnapshotTick=this.moveTicks,s}stepOneMoveTick(){for(;;){let e=this.parser.nextBlock();if(!e)return this.exhausted=!0,!1;if(this.handleBlock(e),e.type===2)return this.moveTicks+=1,this.tickCount=this.moveTicks,this.advanceProjectiles(),this.advanceItems(),this.removeExpiredExplosions(),this.updateCameraAndHud(),!0}}handleBlock(e){if(e.type===0&&this.isPacketData(e.parsed)){let t=e.parsed;this.processControlObject(t.gameState);let n=t.gameState.controlObjectData;if(n){let e=this.getAbsoluteRotation(n);e&&(this.absoluteYaw=e.yaw,this.absolutePitch=e.pitch,this.lastAbsYaw=e.yaw,this.lastAbsPitch=e.pitch)}for(let e of t.events){let t=this.registry.getEventParser(e.classId)?.name;this.processEvent(e,t)}for(let e of t.ghosts)this.processGhostUpdate(e);return}if(e.type===3&&this.isInfoData(e.parsed)){this.firstPerson=(e.parsed.value1&255)!=0,Number.isFinite(e.parsed.value2)&&(this.latestFov=e.parsed.value2);return}if(e.type===2&&this.isMoveData(e.parsed)){this.absoluteYaw+=e.parsed.yaw??0;let t=Math.PI*2;this.absoluteYaw=(this.absoluteYaw%t+t)%t,this.absolutePitch=l(this.absolutePitch+(e.parsed.pitch??0),-u,u)}}buildSnapshot(){let e=this.buildEntityList(),t=this.getTimeSec(),n=this._snap,{chatMessages:r,audioEvents:i}=this.buildTimeFilteredEvents(t),a=n&&n.weaponsHudGen===this._weaponsHudGen?n.weaponsHud:{slots:Array.from(this.weaponsHud.slots.entries()).map(([e,t])=>({index:e,ammo:t})),activeIndex:this.weaponsHud.activeIndex},o=n&&n.inventoryHudGen===this._inventoryHudGen?n.inventoryHud:{slots:Array.from(this.inventoryHud.slots.entries()).map(([e,t])=>({slot:e,count:t})),activeSlot:this.inventoryHud.activeSlot},s=n&&n.backpackPackIndex===this.backpackHud.packIndex&&n.backpackActive===this.backpackHud.active&&n.backpackText===this.backpackHud.text?n.backpackHud:this.backpackHud.packIndex>=0?{...this.backpackHud}:null,c,l;if(n&&n.teamScoresGen===this._teamScoresGen&&n.rosterGen===this._rosterGen)c=n.teamScores,l=n.playerRoster;else{c=this.teamScores.map(e=>({...e}));let e=new Map;for(let{teamId:t}of this.playerRoster.values())t>0&&e.set(t,(e.get(t)??0)+1);for(let t of c)t.playerCount=e.get(t.teamId)??0;l=[];for(let[e,t]of this.playerRoster)l.push({clientId:e,...t})}return this._snap={teamScoresGen:this._teamScoresGen,rosterGen:this._rosterGen,teamScores:c,playerRoster:l,weaponsHudGen:this._weaponsHudGen,weaponsHud:a,inventoryHudGen:this._inventoryHudGen,inventoryHud:o,backpackPackIndex:this.backpackHud.packIndex,backpackActive:this.backpackHud.active,backpackText:this.backpackHud.text,backpackHud:s},{timeSec:t,exhausted:this.exhausted,camera:this.camera,entities:e,controlPlayerGhostId:this.controlPlayerGhostId,playerSensorGroup:this.playerSensorGroup,status:this.lastStatus,chatMessages:r,audioEvents:i,weaponsHud:a,backpackHud:s,inventoryHud:o,teamScores:c,playerRoster:l,connectedClientId:this.connectedClientId,matchClockMs:this.computeMatchClockMs(t)}}isPacketData(e){return!!e&&typeof e==`object`&&`gameState`in e&&`events`in e&&`ghosts`in e}isMoveData(e){return!!e&&typeof e==`object`&&`yaw`in e}isInfoData(e){return!!e&&typeof e==`object`&&`value1`in e&&typeof e.value1==`number`&&`value2`in e&&typeof e.value2==`number`}};async function v(t){let n=new e(new Uint8Array(t)),{header:r,initialBlock:i}=await n.load(),a=h(i.demoValues),o=new _(n);return o.missionDisplayName=a.missionDisplayName,o.missionTypeDisplayName=a.missionType,o.gameClassName=a.gameClassName,o.serverDisplayName=a.serverDisplayName,o.connectedPlayerName=a.recorderName,o.connectedClientId=a.recorderClientId,{source:`demo`,duration:r.demoLengthMs/1e3,missionName:i.missionName??null,gameType:a.missionType,serverDisplayName:a.serverDisplayName,recorderName:a.recorderName,recordingDate:a.recordingDate,streamingPlayback:o}}export{v as createDemoStreamingRecording}; |