Skip to content

Commit

Permalink
Created files
Browse files Browse the repository at this point in the history
  • Loading branch information
Aneks1 committed Dec 2, 2022
0 parents commit b88660c
Show file tree
Hide file tree
Showing 31 changed files with 779 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"overrides": [
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"prefer-const": "warn",
"max-params": "warn",
"no-array-constructor": "warn",
"no-const-assign": "warn",
"no-continue": "warn",
"no-multi-assign": "warn",
"no-unused-expressions": "warn",
"no-undefined": "warn"
}
}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
dist/
tsconfig.json
package-lock.json
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
![Title](./assets/logo_big.png)

geometry-dash.js is an [npm](https://www.npmjs.com/) library which you can use to interact easily with [Geometry Dash's](https://www.robtopgames.com/) servers. People is not meant to access this servers, but with some reverse ingeneering, we can get access to them to recieve and post data.

# Instalation

```cmd
npm install geometry-dash.js
yarn add geometry-dash.js
```

# Links

- [Discord](https://discord.gg/g9dcNqGkzd)
51 changes: 51 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Endpoints

- acceptGJFriendRequest20
- blockGJUser20
- deleteGJAccComment2
- deleteGJComment20
- deleteGJFriendRequests20
- deleteGJLevelUser20
- deleteGJMessages20
- downloadGJLevel22
- downloadGJMessage20
# [getAccountURL] - Not Needed
- getGJAccountComments20
- getGJChallenges
- getGJCommentHistory
- getGJComments21
- getGJDailyLevel
- getGJFriendRequests20
- getGJGauntlets21
- getGJLevelScores211
- getGJLevels21
- getGJMapPacks21
- getGJMessages20
- getGJRewards
- getGJScores20
# - getGJSongInfo - Need class
- [getGJTopArtists]
# - getGJUserInfo20 - Need accountId and gjp params for Client class
- [getGJUserList20]
- getGJUsers20
- getSaveData
- getTop1000
- likeGJItem211
- rateGJDemon21
- rateGJStars211
- readGJFriendRequest20
- removeGJFriend20
- reportGJLevel
- requestUserAccess
- restoreGJItems
- suggestGJStars
- testSong
- unblockGJUser20
- updateGJAccSettings20
- updateGJDesc20
- updateGJUserScore22
- uploadFriendRequest20
- [uploadGJAccComment20]
- [uploadGJComment21]
- uploadGJLevel21
- uploadGJMessage20
Binary file added assets/logo_big.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "geometry-dash.js-v2",
"version": "2.0.0",
"description": "Geometry Dash API Wrapper Package",
"main": "dist/index.js",
"scripts": {
"test": "tsc -p . && node tests/test.js"
},
"author": "Aneks",
"license": "ISC",
"dependencies": {
"@types/node": "^18.11.5",
"@types/sha1": "^1.1.3",
"axios": "^0.26.1",
"sha1": "^1.1.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.41.0",
"@typescript-eslint/parser": "^5.41.0",
"eslint": "^8.26.0"
}
}
18 changes: 18 additions & 0 deletions src/Endpoints/getGJSongInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import formatResponse from "../Utils/formatResponse"
import httpClient from "../Utils/httpClient"
import params from "../Utils/params"

/**
* @param songID The Newgounds ID of the song you want to get.
*/

export default async function getSongInfo(songID: string) {
const data = await httpClient.post('getGJSongInfo', {
secret: params.secrets.common,
songID: songID,
}) as string

console.log(data)
const formatted = formatResponse(data, '~|~')
console.log(formatted)
}
31 changes: 31 additions & 0 deletions src/Endpoints/getGJTopArtists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Artist from "../Structures/ApiStructures/Artist"
import { getTopArtistsOptions } from "../../types/options"
import formatResponse from "../Utils/formatResponse"
import httpClient from "../Utils/httpClient"
import params from "../Utils/params"
import { Collection } from "../Structures/Collection"
import { ErrorCode } from "../../types/types"

/**
* @param options More options for getting the artists (page)
*/

export default async function getTopArtists(options?: getTopArtistsOptions): Promise<Collection<string, Artist> | ErrorCode> {
const data = await httpClient.post('getGJTopArtists', {
secret: params.secrets.common,
page: options?.page?.toString() || '0'
})

const dataArr = data.split(/\||#/)
const allArtists: Collection<string, Artist> = new Collection()
const pageInfo = ( Array.isArray(dataArr)? dataArr.pop() as string : ( dataArr as string ).replace('#', '') ).split(':')
if(pageInfo[0] < pageInfo[1] + allArtists.size) return '-2'

for(const artist of dataArr) {
const formatted = formatResponse(artist, ':')
const artistObj = new Artist(formatted)
allArtists.set(artistObj.name, artistObj)
}

return allArtists
}
18 changes: 18 additions & 0 deletions src/Endpoints/getGJUserInfo20.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import User from "../Structures/ApiStructures/User"
import formatResponse from "../Utils/formatResponse"
import httpClient from "../Utils/httpClient"
import params from "../Utils/params"

/**
* @param userID The Geometry Dash account ID from the user you want to get.
*/

export default async function getUserFromID(userID: string): Promise<User> {
const data = await httpClient.post('getGJUserInfo20', {
secret: params.secrets.common,
targetAccountID: userID
})

const formatted = formatResponse(data, ':')
return new User(formatted)
}
17 changes: 17 additions & 0 deletions src/Structures/ApiStructures/Artist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { FormattedResponse, SocialBaseUrl, SocialLink } from "../../../types/types";

export default class Artist {
public readonly name: string
public readonly youtube: SocialLink<SocialBaseUrl.youtube> | null

constructor(data: FormattedResponse) {
data = Artist.parseData(data)
this.name = data['4']
this.youtube = data['7'] == '' ? null : data['7'] as SocialLink<SocialBaseUrl.youtube> | null
}

private static parseData(data: FormattedResponse): FormattedResponse {
data['7'] = ( data['7'] ? `https://youtube.com/channel/${data["7"]}` : '' )
return data
}
}
42 changes: 42 additions & 0 deletions src/Structures/ApiStructures/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { UserAccountData, UserSocialData, UserStatData } from "../../../types/apiData";
import { FormattedResponse, SocialBaseUrl, SocialLink } from "../../../types/types";

export default class User {
public readonly info: UserAccountData
public readonly stats: UserStatData
public readonly social: UserSocialData

constructor(data: FormattedResponse) {

data = User.parseData(data)

this.info = {
username: data['1'],
accountID: data['2'],
playerID: data['16']
}

this.stats = {
globalRank: data['30'] == '0' ? null : data['30'],
stars: data['3'],
diamonds: data['46'],
coins: data['13'],
userCoins: data['17'],
demons: data['4'],
creatorPoints: data['8']
}

this.social = {
youtube: data['20'] == '' ? null : data['20'] as SocialLink<SocialBaseUrl.youtube> | null,
twitch: data['45'] == '' ? null : data['45'] as SocialLink<SocialBaseUrl.twitch> | null,
twitter: data['44'] == '' ? null : data['44'] as SocialLink<SocialBaseUrl.twitter> | null,
}
}

private static parseData(data: FormattedResponse): FormattedResponse {
data['20'] = ( data['20'] == '' ? data['20'] : `https://youtube.com/channel/${data["20"]}` )
data['45'] = ( data['45'] == '' ? data['45'] : `https://twitch.tv/${data["45"]}` )
data['44'] = ( data['44'] == '' ? data['44'] : `https://twitter.com/${data["44"]}` )
return data
}
}
11 changes: 11 additions & 0 deletions src/Structures/Collection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
interface CollectionConstructor {
new(): Collection<unknown, unknown>;
new<K, V>(entries?: readonly (readonly [K, V])[] | null): Collection<K, V>;
readonly prototype: Collection<unknown, unknown>;
}

export interface Collection<K, V> extends Map<K, V> {
constructor: CollectionConstructor
}

export class Collection<K, V> extends Map<K, V> {}
27 changes: 27 additions & 0 deletions src/Structures/Errors/GDApiError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { format } from "util"
import { ErrorCode, GDSearchParams } from "../../../types/types"
import ErrorMessage from "../../Utils/errorMessages"

export default class GDAPIError extends Error {

private readonly errorCode: ErrorCode
private readonly endpoint: string

constructor({ cause, errorCode, endpoint }: { cause: string, errorCode: ErrorCode, endpoint: string }) {

super()
this.name = 'GDAPIError'
this.errorCode = errorCode
this.endpoint = endpoint
this.message = `${endpoint}.php: Got Response ${errorCode} (${cause}). `

}

private getMessage(params: GDSearchParams) {

this.message += `${new ErrorMessage(params).errorMessages[this.endpoint][this.errorCode]}`
this.message = format(this.message, params)

}

}
14 changes: 14 additions & 0 deletions src/Structures/Errors/GDPostError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default class GDPostError extends Error {

private readonly endpoint: string

constructor(msg: string, endpoint: string) {

super()
this.name = 'GDPostError'
this.endpoint = endpoint
this.message = `${endpoint}: ${msg}`

}

}
44 changes: 44 additions & 0 deletions src/Structures/Managers/Client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import encryptor from "../../Utils/encryptor"
import httpClient from "../../Utils/httpClient"
import params from "../../Utils/params"
import generateUUID from "../../Utils/uuid"
import CommentManager from "./CommentManager"
import RelationshipsManager from "./RelationshipManager"

export default class Client {

public username: string | null = null
public accountID: string | null = null
public playerID: string | null = null
public gjp: string | null = null

public comments: CommentManager | null = null
public relationships: RelationshipsManager | null = null

/**
* @param username Your Geometry Dash account username
* @param password Your Geometry Dash account password
*/

public async login(username: string, password: string): Promise<Client> {

const data = await httpClient.post('accounts/loginGJAccount', {
secret: params.secrets.account,
udid: generateUUID(),
userName: username,
password: password
})

const split = data.split(',')

this.username = username
this.accountID = split[0]
this.playerID = split[1]
this.gjp = encryptor.xor.encrypt(password, 37526)

this.comments = new CommentManager(this)

return this
}

}
Loading

0 comments on commit b88660c

Please sign in to comment.