A Cloudflare Worker designed to proxy Lunar Client's 1.8.9 multiver changes.
constYML_URL='https://launcherupdates.lunarclientcdn.com/latest.yml';constAPI_URL='https://api.lunarclientprod.com/launcher/launch';YML_URL: Points to the Lunar Client's latest.yml file, which contains the version info of the Lunar Client launcher.API_URL: This is the endpoint for Lunar Client's launcher API. Requests to this endpoint allow interaction with the launcher’s backend.
exportdefault{asyncfetch(request,env,ctx){try{returnawaithandleRequest(request,env);}catch(error){console.error('Error:',error.message);returnnewResponse('Internal Server Error.',{status: 500});}}};- This listener is triggered when the worker receives a fetch event. It forwards the request to the
handleRequestfunction. If an error occurs, it catches and logs it, returning a500 Internal Server Errorresponse.
asyncfunctionhandleRequest(request,env){consturl=newURL(request.url);if(request.method==='GET'){returnawaithandleGetRequest(request,env);}else{returnnewResponse('Method Not Allowed',{status: 405});}}Routing logic:
- For any
GETrequests, it callshandleGetRequest. - Any other HTTP methods result in a
405 Method Not Allowedresponse.
asyncfunctionfetchLatestLauncherVersion(env){try{constcachedVersion=awaitenv.KV.get('latestVersion');if(cachedVersion){console.log('Cached version found:',cachedVersion);returncachedVersion;}}catch(error){console.error('Error accessing KV:',error.message);}try{constresponse=awaitfetch(YML_URL);if(!response.ok)thrownewError(`Failed to fetch YML content: ${response.status}`);constymlContent=awaitresponse.text();constmatch=ymlContent.match(/version:\s*(.+)/);constlatestVersion=match ? match[1] : '1.0.0';if(env.KV){awaitenv.KV.put('latestVersion',latestVersion,{expirationTtl: 3600});}returnlatestVersion;}catch(error){console.error('Error fetching latest version:',error.message);return'1.0.0';}}Fetching the latest version:
- The function first checks Cloudflare KV storage for a cached version of the launcher.
- If no cache is found, it fetches the
latest.ymlfile to extract the version. - If successful, the fetched version is cached in KV storage for an hour (
expirationTtl: 3600).
asyncfunctionhandleGetRequest(request,env){constuserAgent=request.headers.get('user-agent');if(userAgent.includes('Discord')){returnnewResponse(generateDiscordHtml(),{headers: {'Content-Type': 'text/html'}});}constversion=awaitfetchLatestLauncherVersion(env);constapiResponse=awaitfetch(API_URL,{method: 'POST',headers: {'Content-Type': 'application/json; charset=UTF-8','User-Agent': `Lunar Client Launcher v${version}`,},body: JSON.stringify({version: '1.8.9',branch: 'master',os: 'win32',arch: 'x64',launcher_version: version,hwid: '0',installation_id: crypto.randomUUID(),os_release: '10.0.22621',}),});if(!apiResponse.ok){console.error(`API request failed: ${apiResponse.status}`);returnnewResponse('API request failed.',{status: 502});}constapiData=awaitapiResponse.json();returnnewResponse(JSON.stringify(apiData),{headers: {'Content-Type': 'application/json','Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload','X-Content-Type-Options': 'nosniff','X-Frame-Options': 'DENY','X-XSS-Protection': '1; mode=block','Referrer-Policy': 'no-referrer','Permissions-Policy': 'geolocation=(), microphone=(), camera=()',},});}- Discord check: If the request is from a Discord bot (based on the user agent), it generates an HTML page with Open Graph metadata.
- API request: Sends a
POSTrequest to Lunar Client’s launcher API with the latest version, system details, and random UUIDs for tracking. - Headers: Adds several security-related headers like
Strict-Transport-Security,X-Frame-Options, etc.
functiongenerateDiscordHtml(){return` <!DOCTYPE html> <html> <head> <title>Multiver Proxy</title> <meta property="og:title" content="multiver Proxy" /> <meta property="og:description" content="A proxy that makes a POST request to Lunar Client's API for you. Made by unethical ❤️" /> <meta property="og:image" content="https://unethicalcdn.com/transparent%20logo.png" /> <meta name="theme-color" content="#2b2d31" /> </head> <body> </body> </html> `;}- Generates a basic HTML page with Open Graph tags for Discord embeds, describing the service provided by the worker proxy.