Skip to content

Commit

Permalink
feat: add patching of game client
Browse files Browse the repository at this point in the history
  • Loading branch information
Tandashi committed May 17, 2024
1 parent 31e2536 commit 74d6e11
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,72 @@ function createWindow(): void {
win.focus()
})

ipcMain.on(
'patch-game-client',
async (event, args: { basePath: string; gameVersion: number }) => {
event.returnValue = undefined

const gameDirPath = path.join(
args.basePath,
args.gameVersion == 1 ? 'highRes' : 'lowRes',
'KnockoutCity'
)

const gameExePath = path.join(gameDirPath, 'KnockoutCity.exe')
const backupGameExePath = path.join(gameDirPath, 'KnockoutCity.exe.bak')

if (!fse.existsSync(backupGameExePath)) {
console.log(`Backing up ${gameExePath} to ${backupGameExePath}`)
fse.copySync(gameExePath, backupGameExePath)
}

let data = await fse.readFile(backupGameExePath).catch((error) => {
console.error('Failed to read Game File:', error)
throw Error('Failed to read Game File')
})

const patches: {
name: string
startAddress: number
endAddress: number
replacement: () => Buffer
}[] = [
{
name: 'Signature Verification',
startAddress: 0x3cad481,
endAddress: 0x3cad485,
replacement: () => Buffer.from([0xb8, 0x01, 0x00, 0x00])
},
{
name: 'Auth Provider',
startAddress: 0x4f97230,
endAddress: 0x4f97233,
replacement: () => Buffer.from([0x78, 0x79, 0x7a])
}
]

for (const patch of patches) {
console.log(`Patching ${patch.name}...`)
const startBuffer = data.subarray(0, patch.startAddress)
const endBuffer = data.subarray(patch.endAddress)

console.log('data pre')
console.log(data.subarray(patch.startAddress, patch.endAddress))
data = Buffer.concat([startBuffer, patch.replacement(), endBuffer])

console.log('data post')
console.log(data.subarray(patch.startAddress, patch.endAddress))
}

await fse.writeFile(gameExePath, data).catch((error) => {
console.error('Failed to write patched Game File:', error)
throw Error('Failed to write patched Game File')
})

event.sender.send('patched-game-client')
}
)

ipcMain.on('set-RPCstate', async (event, arg) => {
event.returnValue = 'ok'

Expand Down
2 changes: 2 additions & 0 deletions src/preload/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ declare global {
getGameState: () => 'installed' | 'deprecated' | 'notInstalled'
getGameInstalls: () => string[]

patchGameClient: () => Promise<void>

installGame: (props: {
setGameState: (state: 'installed' | 'deprecated' | 'notInstalled' | 'installing') => void
setInstallData: (data: number) => void
Expand Down
12 changes: 12 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,18 @@ window.addEventListener('DOMContentLoaded', () => {
return result
}

// @ts-ignore (define in dts)
window.patchGameClient = (): Promise<void> => {
return new Promise((resolve) => {
ipcRenderer.once('patched-game-client', () => resolve())

ipcRenderer.sendSync('patch-game-client', {
basePath: localStorage.getItem('gameDirectory'),
gameVersion: localStorage.getItem('gameVersion')
})
})
}

// @ts-ignore (define in dts)
window.getGameInstalls = (): string[] => {
const result = ipcRenderer.sendSync('get-game-installs', {
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/src/components/LaunchSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ function LaunchSection(): JSX.Element {
setCurrServerName(localStorage.getItem('currServerName') || 'localhost')
setCurrServerType(localStorage.getItem('currServerType') || 'private')

setPopUpState('patchGameClient')
await window.patchGameClient()

if (localStorage.getItem('currServerType') === 'public') {
setPopUpState('authenticating')
if (
Expand Down
3 changes: 3 additions & 0 deletions src/renderer/src/components/popUp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Authenticating from './views/Authenticating'
import ConfirmLogout from './views/ConfirmLogout'
import SelectUninstall from './views/SelectUninstall'
import AccountSettings from './views/AccountSettings'
import PatchGameClient from './views/PatchGameClient'

// States
import { useUIState } from '@renderer/states/uiState'
Expand Down Expand Up @@ -271,6 +272,8 @@ function PopUp(): JSX.Element {
return <SelectUninstall />
case 'accountSettings':
return <AccountSettings />
case 'patchGameClient':
return <PatchGameClient />
default:
return <></>
}
Expand Down
39 changes: 39 additions & 0 deletions src/renderer/src/components/popUp/views/PatchGameClient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Backdrop, Box, Typography, LinearProgress } from '@mui/material'

function PatchGameClient(): JSX.Element {
return (
<Backdrop open={true} style={{ zIndex: 1000 }}>
<Box
style={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
backgroundColor: '#1a1a1a',
width: '600px',
height: '175px',
borderRadius: '5px',
padding: '10px',
textAlign: 'center'
}}
>
<Typography
variant="h4"
style={{
color: 'white',
textAlign: 'center',
marginTop: '20px',
fontFamily: 'Brda',
fontStyle: 'italic',
letterSpacing: '2px'
}}
>
Patch Game Client
</Typography>
<p>Patching the Game Client...</p>
<LinearProgress color="secondary" style={{ opacity: 1, width: '200px' }} />
</Box>
</Backdrop>
)
}

export default PatchGameClient

0 comments on commit 74d6e11

Please sign in to comment.