Skip to content

Commit

Permalink
fix: add fallback peerjs discovery server to bypass geo restrictions …
Browse files Browse the repository at this point in the history
…and because sometimes official server is down

feat: allow to use custom peerjs server via config
  • Loading branch information
zardoy committed Sep 30, 2024
1 parent 2953554 commit ab5f6ab
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 19 deletions.
2 changes: 2 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"defaultHost": "<from-proxy>",
"defaultProxy": "proxy.mcraft.fun",
"mapsProvider": "https://maps.mcraft.fun/",
"peerJsServer": "",
"peerJsServerFallback": "https://p2p.mcraft.fun",
"promoteServers": [
{
"ip": "kaboom.pw",
Expand Down
1 change: 1 addition & 0 deletions prismarine-viewer/viewer/lib/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ export class Entities extends EventEmitter {
}

update (entity: import('prismarine-entity').Entity & { delete?; pos }, overrides) {
console.log('entity', entity)
const isPlayerModel = entity.name === 'player'
if (entity.name === 'zombie' || entity.name === 'zombie_villager' || entity.name === 'husk') {
overrides.texture = `textures/1.16.4/entity/${entity.name === 'zombie_villager' ? 'zombie_villager/zombie_villager.png' : `zombie/${entity.name}.png`}`
Expand Down
1 change: 1 addition & 0 deletions src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ export type ConnectOptions = {
serverIndex?: string
/** If true, will show a UI to authenticate with a new account */
authenticatedAccount?: AuthenticatedAccount | true
peerOptions?: any
}
7 changes: 3 additions & 4 deletions src/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,9 @@ customEvents.on('gameLoaded', () => {
const isWalking = Math.abs(speed.x) > WALKING_SPEED || Math.abs(speed.z) > WALKING_SPEED
const isSprinting = Math.abs(speed.x) > SPRINTING_SPEED || Math.abs(speed.z) > SPRINTING_SPEED
const newAnimation = isWalking ? (isSprinting ? 'running' : 'walking') : 'idle'
const username = e.username!
if (newAnimation !== playerPerAnimation[username]) {
if (newAnimation !== playerPerAnimation[id]) {
viewer.entities.playAnimation(e.id, newAnimation)
playerPerAnimation[username] = newAnimation
playerPerAnimation[id] = newAnimation
}
}
})
Expand Down Expand Up @@ -122,7 +121,7 @@ customEvents.on('gameLoaded', () => {
}
viewer.entities.addListener('remove', (e) => {
loadedSkinEntityIds.delete(e.id)
playerPerAnimation[e.username] = ''
playerPerAnimation[e.id] = ''
bot.tracker.stopTrackingEntity(e, true)
})

Expand Down
3 changes: 3 additions & 0 deletions src/globalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ export type AppConfig = {
defaultProxy?: string
// defaultProxySave?: string
// defaultVersion?: string
peerJsServer?: string
peerJsServerFallback?: string
promoteServers?: Array<{ ip, description, version? }>
mapsProvider?: string
}
Expand All @@ -120,6 +122,7 @@ export const miscUiState = proxy({
singleplayer: false,
flyingSquid: false,
wanOpened: false,
wanOpening: false,
/** wether game hud is shown (in playing state) */
gameLoaded: false,
showUI: true,
Expand Down
11 changes: 8 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ import defaultServerOptions from './defaultLocalServerOptions'
import dayCycle from './dayCycle'

import { onAppLoad, resourcepackReload } from './resourcePack'
import { connectToPeer } from './localServerMultiplayer'
import { ConnectPeerOptions, connectToPeer } from './localServerMultiplayer'
import CustomChannelClient from './customClient'
import { loadScript } from 'prismarine-viewer/viewer/lib/utils'
import { registerServiceWorker } from './serviceWorker'
Expand Down Expand Up @@ -486,7 +486,7 @@ async function connect (connectOptions: ConnectOptions) {
port: server.port ? +server.port : undefined,
version: connectOptions.botVersion || false,
...p2pMultiplayer ? {
stream: await connectToPeer(connectOptions.peerId!),
stream: await connectToPeer(connectOptions.peerId!, connectOptions.peerOptions),
} : {},
...singleplayer || p2pMultiplayer ? {
keepAlive: false,
Expand Down Expand Up @@ -1022,6 +1022,10 @@ downloadAndOpenFile().then((downloadAction) => {
void Promise.resolve().then(() => {
// try to connect to peer
const peerId = qs.get('connectPeer')
const peerOptions = {} as ConnectPeerOptions
if (qs.get('server')) {
peerOptions.server = qs.get('server')!
}
const version = qs.get('peerVersion')
if (peerId) {
let username: string | null = options.guestUsername
Expand All @@ -1031,7 +1035,8 @@ downloadAndOpenFile().then((downloadAction) => {
void connect({
username,
botVersion: version || undefined,
peerId
peerId,
peerOptions
})
}
})
Expand Down
86 changes: 77 additions & 9 deletions src/localServerMultiplayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class CustomDuplex extends Duplex {

let peerInstance: Peer | undefined

let overridePeerJsServer = null as string | null

export const getJoinLink = () => {
if (!peerInstance) return
const url = new URL(window.location.href)
Expand All @@ -27,6 +29,11 @@ export const getJoinLink = () => {
}
url.searchParams.set('connectPeer', peerInstance.id)
url.searchParams.set('peerVersion', localServer!.options.version)
const host = (overridePeerJsServer ?? miscUiState.appConfig?.peerJsServer) ?? undefined
if (host) {
// TODO! use miscUiState.appConfig.peerJsServer
url.searchParams.set('server', host)
}
return url.toString()
}

Expand All @@ -46,8 +53,12 @@ export const openToWanAndCopyJoinLink = async (writeText: (text) => void, doCopy
if (doCopy) await copyJoinLink()
return 'Already opened to wan. Join link copied'
}
miscUiState.wanOpening = true
const host = (overridePeerJsServer ?? miscUiState.appConfig?.peerJsServer) || undefined
const params = host ? parseUrl(host) : undefined
const peer = new Peer({
debug: 3,
...params
})
peerInstance = peer
peer.on('connection', (connection) => {
Expand Down Expand Up @@ -83,34 +94,91 @@ export const openToWanAndCopyJoinLink = async (writeText: (text) => void, doCopy
connection.on('close', disconnected)
connection.on('error', disconnected)
})
const fallbackServer = miscUiState.appConfig?.peerJsServerFallback
const hasFallback = fallbackServer && peer.options.host !== fallbackServer
let hadErrorReported = false
peer.on('error', (error) => {
console.error(error)
writeText(error.message)
console.error('peerJS error', error)
if (error.type === 'server-error' && hasFallback) {
return
}
hadErrorReported = true
writeText(error.message || JSON.stringify(error))
})
return new Promise<string>(resolve => {
let timeout
const destroy = () => {
clearTimeout(timeout)
timeout = undefined
peer.destroy()
peerInstance = undefined
}

const result = await new Promise<string>(resolve => {
peer.on('open', async () => {
await copyJoinLink()
resolve('Copied join link to clipboard')
})
setTimeout(() => {
timeout = setTimeout(() => {
if (!hadErrorReported && timeout !== undefined) {
writeText('timeout')
}
resolve('Failed to open to wan (timeout)')
}, 5000)
}, 6000)

// fallback
peer.on('error', async (error) => {
if (!peer.open) {
if (hasFallback) {
destroy()

overridePeerJsServer = fallbackServer
console.log('Trying fallback server', fallbackServer)
resolve((await openToWanAndCopyJoinLink(writeText, doCopy))!)
}
}
})
})
if (!peerInstance.open) {
destroy()
}
miscUiState.wanOpening = false
return result
}

const parseUrl = (url: string) => {
// peerJS does this internally for some reason: const url = new URL(`${protocol}://${host}:${port}${path}${key}/${method}`)
if (!url.startsWith('http')) url = `${location.protocol}//${url}`
const urlObj = new URL(url)
const key = urlObj.searchParams.get('key')
return {
host: urlObj.hostname,
path: urlObj.pathname,
protocol: urlObj.protocol.slice(0, -1),
...urlObj.port ? { port: +urlObj.port } : {},
...key ? { key } : {},
}
}

export const closeWan = () => {
if (!peerInstance) return
peerInstance.destroy()
peerInstance?.destroy()
peerInstance = undefined
miscUiState.wanOpened = false
return 'Closed to wan'
return 'Closed WAN'
}

export type ConnectPeerOptions = {
server?: string
}

export const connectToPeer = async (peerId: string) => {
export const connectToPeer = async (peerId: string, options: ConnectPeerOptions = {}) => {
setLoadingScreenStatus('Connecting to peer server')
// todo destroy connection on error
// TODO! use miscUiState.appConfig.peerJsServer
const host = options.server
const params = host ? parseUrl(host) : undefined
const peer = new Peer({
debug: 3,
...params
})
await resolveTimeout(new Promise(resolve => {
peer.once('open', resolve)
Expand Down
9 changes: 6 additions & 3 deletions src/react/PauseScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export default () => {
const isModalActive = useIsModalActive('pause-screen')
const fsStateSnap = useSnapshot(fsState)
const activeModalStackSnap = useSnapshot(activeModalStack)
const { singleplayer, wanOpened } = useSnapshot(miscUiState)
const { singleplayer, wanOpened, wanOpening } = useSnapshot(miscUiState)

const handlePointerLockChange = () => {
if (!pointerLock.hasPointerLock && activeModalStack.length === 0) {
Expand Down Expand Up @@ -188,7 +188,10 @@ export default () => {
return
}
if (!wanOpened || !qr) {
await openToWanAndCopyJoinLink(() => { }, !qr)
await openToWanAndCopyJoinLink((err) => {
if (!miscUiState.wanOpening) return
alert(`Something went wrong: ${err}`)
}, !qr)
}
if (qr) {
const joinLink = getJoinLink()
Expand Down Expand Up @@ -230,7 +233,7 @@ export default () => {
{singleplayer ? (
<div className={styles.row}>
<Button className="button" style={{ width: '170px' }} onClick={async () => clickJoinLinkButton()}>
{wanOpened ? 'Close Wan' : 'Copy Join Link'}
{wanOpening ? 'Opening, wait...' : wanOpened ? 'Close Wan' : 'Copy Join Link'}
</Button>
{(navigator.share as typeof navigator.share | undefined) ? (
<Button
Expand Down

0 comments on commit ab5f6ab

Please sign in to comment.