diff --git a/README.md b/README.md index d8fef72..b01ff24 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # csgo-sharecode -JS module to decode / encode CSGO share codes used to share game replays/crosshairs between players. +JS module to decode / encode CS:GO and CS2 share codes used to share game replays/crosshairs between players. # Installation @@ -62,32 +62,33 @@ Decodes a crosshair share code into a `Crosshair` object. ```ts import { decodeCrosshairShareCode, Crosshair } from 'csgo-sharecode'; -const shareCode = 'CSGO-Cn37R-YE7vo-pLCAL-aURmZ-z6zkG'; +const shareCode = 'CSGO-WsnnD-eHaMw-QNDf9-oxuDh-ydOUD'; const crosshair: Crosshair = decodeCrosshairShareCode(shareCode); console.log(crosshair); // output: // // { -// gap: -1.3, -// outline: 2, -// red: 175, -// green: 81, -// blue: 213, -// alpha: 137, -// splitDistance: 6, +// gap: -2.2, +// outline: 1, +// red: 50, +// green: 250, +// blue: 50, +// alpha: 200, +// splitDistance: 3, +// followRecoil: true, // fixedCrosshairGap: 3, -// color: 5, +// color: 1, // outlineEnabled: true, -// innerSplitAlpha: 0.6, -// outerSplitAlpha: 0.4, -// splitSizeRatio: 0.5, -// thickness: 1.2, -// centerDotEnabled: true, +// innerSplitAlpha: 0, +// outerSplitAlpha: 1, +// splitSizeRatio: 1, +// thickness: 0.6, +// centerDotEnabled: false, // deployedWeaponGapEnabled: true, // alphaEnabled: true, -// tStyleEnabled: true, +// tStyleEnabled: false, // style: 2, -// length: 4.6 +// length: 10 // } ``` @@ -99,33 +100,34 @@ Encodes a `Crosshair` object into a crosshair share code. import { encodeCrosshair, Crosshair } from 'csgo-sharecode'; const crosshair: Crosshair = { - gap: -1.3, - outline: 2, - red: 175, - green: 81, - blue: 213, - alpha: 137, - splitDistance: 6, + gap: -2.2, + outline: 1, + red: 50, + green: 250, + blue: 50, + alpha: 200, + splitDistance: 3, fixedCrosshairGap: 3, - color: 5, - innerSplitAlpha: 0.6, + color: 1, + innerSplitAlpha: 0, outlineEnabled: true, - outerSplitAlpha: 0.4, - splitSizeRatio: 0.5, - thickness: 1.2, - centerDotEnabled: true, + outerSplitAlpha: 1, + splitSizeRatio: 1, + thickness: 0.6, + centerDotEnabled: false, alphaEnabled: true, - tStyleEnabled: true, + tStyleEnabled: false, style: 2, - length: 4.6, + length: 10, deployedWeaponGapEnabled: true, + followRecoil: true, }; const shareCode = encodeCrosshair(crosshair); console.log(shareCode); // output: // -// "CSGO-Cn37R-YE7vo-pLCAL-aURmZ-z6zkG" +// "CSGO-WsnnD-eHaMw-QNDf9-oxuDh-ydOUD" ``` ### Generating CSGO ConVars @@ -136,26 +138,27 @@ Utility function to generate CSGO ConVars for a given crosshair. import { crosshairToConVars, Crosshair } from 'csgo-sharecode'; const crosshair: Crosshair = { - gap: -1.3, - outline: 2, - red: 175, - green: 81, - blue: 213, - alpha: 137, - splitDistance: 6, + gap: -2.2, + outline: 1, + red: 50, + green: 250, + blue: 50, + alpha: 200, + splitDistance: 3, fixedCrosshairGap: 3, - color: 5, - innerSplitAlpha: 0.6, + color: 1, + innerSplitAlpha: 0, outlineEnabled: true, - outerSplitAlpha: 0.4, - splitSizeRatio: 0.5, - thickness: 1.2, - centerDotEnabled: true, + outerSplitAlpha: 1, + splitSizeRatio: 1, + thickness: 0.6, + centerDotEnabled: false, alphaEnabled: true, - tStyleEnabled: true, + tStyleEnabled: false, style: 2, - length: 4.6, + length: 10, deployedWeaponGapEnabled: true, + followRecoil: true, }; const conVars = crosshairToConVars(crosshair); @@ -163,25 +166,26 @@ console.log(conVars); // Output: // // cl_crosshair_drawoutline "1" -// cl_crosshair_dynamic_maxdist_splitratio "0.5" -// cl_crosshair_dynamic_splitalpha_innermod "0.6" -// cl_crosshair_dynamic_splitalpha_outermod "0.4" -// cl_crosshair_dynamic_splitdist "6" -// cl_crosshair_outlinethickness "2" -// cl_crosshair_t "1" -// cl_crosshairalpha "137" -// cl_crosshaircolor "5" -// cl_crosshaircolor_b "213" -// cl_crosshaircolor_g "81" -// cl_crosshaircolor_r "175" -// cl_crosshairdot "1" -// cl_crosshairgap "-1.3" +// cl_crosshair_dynamic_maxdist_splitratio "1" +// cl_crosshair_dynamic_splitalpha_innermod "0" +// cl_crosshair_dynamic_splitalpha_outermod "1" +// cl_crosshair_dynamic_splitdist "3" +// cl_crosshair_outlinethickness "1" +// cl_crosshair_t "0" +// cl_crosshairalpha "200" +// cl_crosshaircolor "1" +// cl_crosshaircolor_b "50" +// cl_crosshaircolor_g "250" +// cl_crosshaircolor_r "50" +// cl_crosshairdot "0" +// cl_crosshairgap "-2.2" // cl_crosshairgap_useweaponvalue "1" -// cl_crosshairsize "4.6" +// cl_crosshairsize "10" // cl_crosshairstyle "2" -// cl_crosshairthickness "1.2" +// cl_crosshairthickness "0.6" // cl_crosshairusealpha "1" // cl_fixedcrosshairgap "3" +// cl_crosshair_recoil "1" ``` # License diff --git a/src/__snapshots__/index.test.ts.snap b/src/__snapshots__/index.test.ts.snap index 9450ed3..319cb00 100644 --- a/src/__snapshots__/index.test.ts.snap +++ b/src/__snapshots__/index.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1 -exports[`Crosshair share code > should generate CSGO ConVars from crosshair 1`] = ` +exports[`Crosshair share code > should generate ConVars from crosshair 1`] = ` " cl_crosshair_drawoutline \\"1\\" cl_crosshair_dynamic_maxdist_splitratio \\"0.5\\" @@ -22,10 +22,11 @@ cl_crosshairstyle \\"2\\" cl_crosshairthickness \\"1.2\\" cl_crosshairusealpha \\"1\\" cl_fixedcrosshairgap \\"3\\" +cl_crosshair_recoil \\"0\\" " `; -exports[`Crosshair share code > should generate CSGO ConVars from crosshair 2`] = ` +exports[`Crosshair share code > should generate ConVars from crosshair 2`] = ` " cl_crosshair_drawoutline \\"0\\" cl_crosshair_dynamic_maxdist_splitratio \\"0.3\\" @@ -47,10 +48,11 @@ cl_crosshairstyle \\"3\\" cl_crosshairthickness \\"0.5\\" cl_crosshairusealpha \\"0\\" cl_fixedcrosshairgap \\"3\\" +cl_crosshair_recoil \\"0\\" " `; -exports[`Crosshair share code > should generate CSGO ConVars from crosshair 3`] = ` +exports[`Crosshair share code > should generate ConVars from crosshair 3`] = ` " cl_crosshair_drawoutline \\"0\\" cl_crosshair_dynamic_maxdist_splitratio \\"0.3\\" @@ -72,5 +74,84 @@ cl_crosshairstyle \\"1\\" cl_crosshairthickness \\"0.5\\" cl_crosshairusealpha \\"1\\" cl_fixedcrosshairgap \\"4.3\\" +cl_crosshair_recoil \\"0\\" +" +`; + +exports[`Crosshair share code > should generate ConVars from crosshair 4`] = ` +" +cl_crosshair_drawoutline \\"0\\" +cl_crosshair_dynamic_maxdist_splitratio \\"0.3\\" +cl_crosshair_dynamic_splitalpha_innermod \\"1\\" +cl_crosshair_dynamic_splitalpha_outermod \\"0.5\\" +cl_crosshair_dynamic_splitdist \\"7\\" +cl_crosshair_outlinethickness \\"1\\" +cl_crosshair_t \\"0\\" +cl_crosshairalpha \\"200\\" +cl_crosshaircolor \\"5\\" +cl_crosshaircolor_b \\"50\\" +cl_crosshaircolor_g \\"250\\" +cl_crosshaircolor_r \\"50\\" +cl_crosshairdot \\"1\\" +cl_crosshairgap \\"1\\" +cl_crosshairgap_useweaponvalue \\"1\\" +cl_crosshairsize \\"5\\" +cl_crosshairstyle \\"2\\" +cl_crosshairthickness \\"0.5\\" +cl_crosshairusealpha \\"1\\" +cl_fixedcrosshairgap \\"4.3\\" +cl_crosshair_recoil \\"1\\" +" +`; + +exports[`Crosshair share code > should generate ConVars from crosshair 5`] = ` +" +cl_crosshair_drawoutline \\"1\\" +cl_crosshair_dynamic_maxdist_splitratio \\"1\\" +cl_crosshair_dynamic_splitalpha_innermod \\"0\\" +cl_crosshair_dynamic_splitalpha_outermod \\"1\\" +cl_crosshair_dynamic_splitdist \\"3\\" +cl_crosshair_outlinethickness \\"1\\" +cl_crosshair_t \\"0\\" +cl_crosshairalpha \\"200\\" +cl_crosshaircolor \\"1\\" +cl_crosshaircolor_b \\"50\\" +cl_crosshaircolor_g \\"250\\" +cl_crosshaircolor_r \\"50\\" +cl_crosshairdot \\"0\\" +cl_crosshairgap \\"-2.2\\" +cl_crosshairgap_useweaponvalue \\"1\\" +cl_crosshairsize \\"10\\" +cl_crosshairstyle \\"2\\" +cl_crosshairthickness \\"0.6\\" +cl_crosshairusealpha \\"1\\" +cl_fixedcrosshairgap \\"3\\" +cl_crosshair_recoil \\"1\\" +" +`; + +exports[`Crosshair share code > should generate ConVars from crosshair 6`] = ` +" +cl_crosshair_drawoutline \\"0\\" +cl_crosshair_dynamic_maxdist_splitratio \\"0.5\\" +cl_crosshair_dynamic_splitalpha_innermod \\"0.5\\" +cl_crosshair_dynamic_splitalpha_outermod \\"0.6\\" +cl_crosshair_dynamic_splitdist \\"7\\" +cl_crosshair_outlinethickness \\"1\\" +cl_crosshair_t \\"1\\" +cl_crosshairalpha \\"136\\" +cl_crosshaircolor \\"5\\" +cl_crosshaircolor_b \\"227\\" +cl_crosshaircolor_g \\"88\\" +cl_crosshaircolor_r \\"232\\" +cl_crosshairdot \\"1\\" +cl_crosshairgap \\"-1.2\\" +cl_crosshairgap_useweaponvalue \\"0\\" +cl_crosshairsize \\"7.2\\" +cl_crosshairstyle \\"2\\" +cl_crosshairthickness \\"1.5\\" +cl_crosshairusealpha \\"0\\" +cl_fixedcrosshairgap \\"3\\" +cl_crosshair_recoil \\"1\\" " `; diff --git a/src/index.test.ts b/src/index.test.ts index f1b39cb..4c4796d 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -115,6 +115,7 @@ describe('Crosshair share code', () => { style: 2, length: 4.6, deployedWeaponGapEnabled: true, + followRecoil: false, }, }, { @@ -140,6 +141,7 @@ describe('Crosshair share code', () => { style: 3, length: 5, deployedWeaponGapEnabled: false, + followRecoil: false, }, }, { @@ -165,6 +167,85 @@ describe('Crosshair share code', () => { style: 1, length: 5, deployedWeaponGapEnabled: true, + followRecoil: false, + }, + }, + { + shareCode: 'CSGO-fCUBz-CBHss-a74RP-SEdO8-mvZpG', + crosshair: { + gap: 1, + outline: 1, + red: 50, + green: 250, + blue: 50, + alpha: 200, + splitDistance: 7, + fixedCrosshairGap: 4.3, + color: 5, + innerSplitAlpha: 1, + outlineEnabled: false, + outerSplitAlpha: 0.5, + splitSizeRatio: 0.3, + thickness: 0.5, + centerDotEnabled: true, + alphaEnabled: true, + tStyleEnabled: false, + style: 2, + length: 5, + deployedWeaponGapEnabled: true, + followRecoil: true, + }, + }, + { + shareCode: 'CSGO-WsnnD-eHaMw-QNDf9-oxuDh-ydOUD', + crosshair: { + gap: -2.2, + outline: 1, + red: 50, + green: 250, + blue: 50, + alpha: 200, + splitDistance: 3, + fixedCrosshairGap: 3, + color: 1, + innerSplitAlpha: 0, + outlineEnabled: true, + outerSplitAlpha: 1, + splitSizeRatio: 1, + thickness: 0.6, + centerDotEnabled: false, + alphaEnabled: true, + tStyleEnabled: false, + style: 2, + length: 10, + deployedWeaponGapEnabled: true, + followRecoil: true, + }, + }, + { + shareCode: 'CSGO-ZrEjo-yASEP-OAdce-Sf44w-rhK5O', + crosshair: { + gap: -1.2, + outline: 1, + red: 232, + green: 88, + blue: 227, + alpha: 136, + splitDistance: 7, + fixedCrosshairGap: 3, + color: 5, + innerSplitAlpha: 0.5, + outlineEnabled: false, + outerSplitAlpha: 0.6, + splitSizeRatio: 0.5, + thickness: 1.5, + centerDotEnabled: true, + alphaEnabled: false, + tStyleEnabled: true, + style: 2, + length: 7.2, + deployedWeaponGapEnabled: false, + followRecoil: true, }, }, ]; @@ -181,7 +262,7 @@ describe('Crosshair share code', () => { }); }); - it('should generate CSGO ConVars from crosshair', () => { + it('should generate ConVars from crosshair', () => { crosshairSamples.forEach(({ crosshair }) => { expect(crosshairToConVars(crosshair)).toMatchSnapshot(); }); diff --git a/src/index.ts b/src/index.ts index b606f2c..6d6f64f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,7 @@ export interface Crosshair { thickness: number; centerDotEnabled: boolean; splitDistance: number; + followRecoil: boolean; // CS2 only, always false with CS:GO fixedCrosshairGap: number; innerSplitAlpha: number; outerSplitAlpha: number; @@ -29,12 +30,19 @@ export interface Crosshair { tStyleEnabled: boolean; deployedWeaponGapEnabled: boolean; /** + * CS:GO * 0 => Default * 1 => Default static * 2 => Classic * 3 => Classic dynamic * 4 => Classic static */ + /** + * CS2 + * 0 to 3 => Classic + * 4 => Classic static + * 5 => Legacy + */ style: number; } @@ -162,7 +170,8 @@ export function decodeCrosshairShareCode(shareCode: string): Crosshair { green: bytes[5], blue: bytes[6], alpha: bytes[7], - splitDistance: bytes[8], + splitDistance: bytes[8] & 7, + followRecoil: ((bytes[8] >> 4) & 8) === 8, fixedCrosshairGap: uint8ToInt8(bytes[9]) / 10, color: bytes[10] & 7, outlineEnabled: (bytes[10] & 8) === 8, @@ -191,7 +200,7 @@ export function encodeCrosshair(crosshair: Crosshair): string { crosshair.green, crosshair.blue, crosshair.alpha, - crosshair.splitDistance, + (crosshair.splitDistance & 7) | (Number(crosshair.followRecoil) << 7), (crosshair.fixedCrosshairGap * 10) & 0xff, (crosshair.color & 7) | (Number(crosshair.outlineEnabled) << 3) | ((crosshair.innerSplitAlpha * 10) << 4), (crosshair.outerSplitAlpha * 10) | ((crosshair.splitSizeRatio * 10) << 4), @@ -236,5 +245,6 @@ cl_crosshairstyle "${crosshair.style}" cl_crosshairthickness "${crosshair.thickness}" cl_crosshairusealpha "${Number(crosshair.alphaEnabled)}" cl_fixedcrosshairgap "${crosshair.fixedCrosshairGap}" +cl_crosshair_recoil "${Number(crosshair.followRecoil)}" `; }