Initial commit
This commit is contained in:
135
src/server/profiles/manager.ts
Normal file
135
src/server/profiles/manager.ts
Normal file
@@ -0,0 +1,135 @@
|
||||
import { ServerContentBase } from "../ContentBase.ts";
|
||||
import NameDictionary from "./dict.ts";
|
||||
import Profile from "./profile.ts";
|
||||
import { SelfAccount, type RecNetAccount } from "./types/profile.ts";
|
||||
import Command from "./../commands/command.ts";
|
||||
import z from "zod";
|
||||
import { ProfileRole } from "../platforms/base.ts";
|
||||
|
||||
const profiles: Map<number, Profile> = new Map();
|
||||
|
||||
class ProfileManagerBase extends ServerContentBase {
|
||||
|
||||
static profilesKey = "profiles";
|
||||
static profileByNameKey = "profileName";
|
||||
|
||||
/*async exists(id: number) {
|
||||
return (await this.kv.getKv().get([ ProfileManagerBase.profilesKey, id ])).value !== null
|
||||
}*/
|
||||
|
||||
async #getUnusedId() {
|
||||
let id = Math.round(Math.random() * 2_147_483_647);
|
||||
if (await this.get(id)) id = await this.#getUnusedId();
|
||||
return id;
|
||||
}
|
||||
|
||||
async #getUnusedUsername() {
|
||||
const adjective = NameDictionary.Adjectives[Math.floor(Math.random() * NameDictionary.Adjectives.length)];
|
||||
const noun = NameDictionary.Nouns[Math.floor(Math.random() * NameDictionary.Nouns.length)];
|
||||
const discriminator = Math.round(Math.random() * 1000);
|
||||
let username = `${adjective}${noun}#${discriminator}`;
|
||||
if (await this.getByUsername(username)) username = await this.#getUnusedUsername();
|
||||
return username;
|
||||
}
|
||||
|
||||
async create(username?: string) {
|
||||
const id = await this.#getUnusedId();
|
||||
const newUsername = username? username : await this.#getUnusedUsername();
|
||||
const newProfile: RecNetAccount = {
|
||||
accountId: id,
|
||||
username: newUsername,
|
||||
displayName: newUsername,
|
||||
profileImage: "DefaultProfileImage.png",
|
||||
createdAt: new Date()
|
||||
}
|
||||
await this.kv.getKv().set([ ProfileManagerBase.profilesKey, id ], newProfile);
|
||||
await this.kv.getKv().set([ ProfileManagerBase.profilesKey, newUsername ], id);
|
||||
|
||||
return this.get(id);
|
||||
}
|
||||
|
||||
async get(id: number) {
|
||||
const profile = profiles.get(id);
|
||||
if (!profile) {
|
||||
const info = await this.kv.getKv().get<SelfAccount>([ ProfileManagerBase.profilesKey, id ]);
|
||||
if (!info.value) return null;
|
||||
const prof = new Profile(info.value, this.kv, this.server);
|
||||
profiles.set(id, prof);
|
||||
return prof;
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
async getMany(...ids: number[]) {
|
||||
return (await Promise.all(ids.map(id => this.get(id)))).filter(prof => prof !== null);
|
||||
}
|
||||
|
||||
async getAll() {
|
||||
const keys = this.kv.getKv().list({ prefix: [ ProfileManagerBase.profilesKey ] });
|
||||
const awaitedKeys = await Array.fromAsync(keys);
|
||||
return awaitedKeys.map(entry => entry.key).map(val => val[1]).filter(val => typeof val == 'number');
|
||||
}
|
||||
|
||||
async getByUsername(username: string) {
|
||||
const id = (await this.kv.getKv().get<number>([ ProfileManagerBase.profilesKey, username ])).value;
|
||||
if (typeof id == 'number') return this.get(id);
|
||||
else return id;
|
||||
}
|
||||
|
||||
override start() {
|
||||
this.server.Commands.addRootCommand(new Command({
|
||||
key: ['account', 'profile', 'acc', 'prof'],
|
||||
subcommands: [
|
||||
new Command({
|
||||
key: ['get', 'g', 'fetch', 'f'],
|
||||
exec: async (id: number) => {
|
||||
const prof = await this.get(id);
|
||||
if (!prof) return prof;
|
||||
else return await prof.export();
|
||||
},
|
||||
zod: z.tuple([
|
||||
z.string().transform(Number)
|
||||
]),
|
||||
help: 'Fetch a profile: <id: number>'
|
||||
}),
|
||||
new Command({
|
||||
key: ['getall', 'listall', 'fetchall', 'all', 'a'],
|
||||
exec: async () => {
|
||||
const ids = await this.getAll();
|
||||
return ids;
|
||||
},
|
||||
zod: z.tuple([]),
|
||||
help: 'Fetch all profile IDs'
|
||||
}),
|
||||
new Command({
|
||||
key: ['getrole', 'gr'],
|
||||
exec: async (id: number) => {
|
||||
const profile = await this.get(id);
|
||||
if (!profile) return new Error("No such profile");
|
||||
else return await profile.getRole();
|
||||
},
|
||||
zod: z.tuple([
|
||||
z.string().transform(Number)
|
||||
]),
|
||||
help: 'Set the profile role: <id: number>'
|
||||
}),
|
||||
new Command({
|
||||
key: ['setrole', 'sr'],
|
||||
exec: async (id: number, role: ProfileRole) => {
|
||||
const profile = await this.get(id);
|
||||
if (!profile) return new Error("No such profile");
|
||||
else return await profile.setRole(role);
|
||||
},
|
||||
zod: z.tuple([
|
||||
z.string().transform(Number),
|
||||
z.string()
|
||||
]),
|
||||
help: 'Set the profile role: <id: number, role: "developer" | "moderator" | "screenshare" | "user">'
|
||||
})
|
||||
]
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ProfileManagerBase;
|
||||
Reference in New Issue
Block a user