XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

SpaceNinjaServer

A simple server for a small space ninja game

公开
关注 0 Fork 1 Star 0
UTF-8
import type {
    IGuildDatabase,
    IDojoComponentDatabase,
    ITechProjectDatabase,
    IDojoDecoDatabase,
    ILongMOTD,
    IGuildMemberDatabase,
    IGuildLogEntryNumber,
    IGuildRank,
    IGuildLogRoomChange,
    IGuildLogEntryRoster,
    IGuildLogEntryContributable,
    IDojoLeaderboardEntry,
    IGuildAdDatabase,
    IAllianceDatabase,
    IAllianceMemberDatabase,
    IVaultPendingRecipeDatabase
} from "../types/guildTypes.ts";
import { eGuildPermission } from "../types/guildTypes.ts";
import type { Document, Model } from "mongoose";
import { model, Schema, Types } from "mongoose";
import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel.ts";
import { pictureFrameInfoSchema } from "./personalRoomsModel.ts";
import type { IGoalProgressClient, IGoalProgressDatabase } from "../types/inventoryTypes/inventoryTypes.ts";
import { toOid } from "../helpers/inventoryHelpers.ts";

const dojoDecoSchema = new Schema<IDojoDecoDatabase>({
    Type: String,
    Pos: [Number],
    Rot: [Number],
    Scale: Number,
    Name: String,
    Sockets: Number,
    RegularCredits: Number,
    MiscItems: { type: [typeCountSchema], default: undefined },
    CompletionTime: Date,
    RushPlatinum: Number,
    PictureFrameInfo: pictureFrameInfoSchema,
    Pending: Boolean
});

const dojoLeaderboardEntrySchema = new Schema<IDojoLeaderboardEntry>(
    {
        s: Number,
        r: Number,
        n: String
    },
    { _id: false }
);

const dojoComponentSchema = new Schema<IDojoComponentDatabase>({
    SortId: Schema.Types.ObjectId,
    pf: { type: String, required: true },
    ppf: String,
    pi: Schema.Types.ObjectId,
    op: String,
    pp: String,
    Name: String,
    Message: String,
    RegularCredits: Number,
    MiscItems: { type: [typeCountSchema], default: undefined },
    CompletionTime: Date,
    CompletionLogPending: Boolean,
    RushPlatinum: Number,
    DestructionTime: Date,
    Decos: [dojoDecoSchema],
    DecoCapacity: Number,
    PaintBot: Schema.Types.ObjectId,
    PendingColors: { type: [Number], default: undefined },
    Colors: { type: [Number], default: undefined },
    PendingLights: { type: [Number], default: undefined },
    Lights: { type: [Number], default: undefined },
    Settings: String,
    Leaderboard: { type: [dojoLeaderboardEntrySchema], default: undefined }
});

const techProjectSchema = new Schema<ITechProjectDatabase>(
    {
        ItemType: String,
        ReqCredits: Number,
        ReqItems: [typeCountSchema],
        State: Number,
        CompletionDate: Date
    },
    { _id: false }
);

const longMOTDSchema = new Schema<ILongMOTD>(
    {
        message: String,
        authorName: String,
        authorGuildName: String
    },
    { _id: false }
);

const guildRankSchema = new Schema<IGuildRank>(
    {
        Name: String,
        Permissions: Number
    },
    { _id: false }
);

const defaultRanks: IGuildRank[] = [
    {
        Name: "/Lotus/Language/Game/Rank_Creator",
        Permissions: eGuildPermission.Tactician | eGuildPermission.Host | 16351
    },
    {
        Name: "/Lotus/Language/Game/Rank_Warlord",
        Permissions: eGuildPermission.Tactician | eGuildPermission.Host | 16351
    },
    {
        Name: "/Lotus/Language/Game/Rank_General",
        Permissions: eGuildPermission.Host | 4318
    },
    {
        Name: "/Lotus/Language/Game/Rank_Officer",
        Permissions: eGuildPermission.Host | 4314
    },
    {
        Name: "/Lotus/Language/Game/Rank_Leader",
        Permissions: eGuildPermission.Host | 4106
    },
    {
        Name: "/Lotus/Language/Game/Rank_Sage",
        Permissions: eGuildPermission.Host | 4304
    },
    {
        Name: "/Lotus/Language/Game/Rank_Soldier",
        Permissions: eGuildPermission.Host | 4098
    },
    {
        Name: "/Lotus/Language/Game/Rank_Initiate",
        Permissions: eGuildPermission.Host | eGuildPermission.Fabricator
    },
    {
        Name: "/Lotus/Language/Game/Rank_Utility",
        Permissions: eGuildPermission.Host | eGuildPermission.Fabricator
    }
];

const guildLogRoomChangeSchema = new Schema<IGuildLogRoomChange>(
    {
        dateTime: Date,
        entryType: Number,
        details: String,
        componentId: Types.ObjectId
    },
    { _id: false }
);

const guildLogEntryContributableSchema = new Schema<IGuildLogEntryContributable>(
    {
        dateTime: Date,
        entryType: Number,
        details: String
    },
    { _id: false }
);

const guildLogEntryRosterSchema = new Schema<IGuildLogEntryRoster>(
    {
        dateTime: Date,
        entryType: Number,
        details: String
    },
    { _id: false }
);

const guildLogEntryNumberSchema = new Schema<IGuildLogEntryNumber>(
    {
        dateTime: Date,
        entryType: Number,
        details: Number
    },
    { _id: false }
);

const goalProgressSchema = new Schema<IGoalProgressDatabase>(
    {
        Count: Number,
        Tag: String,
        goalId: Types.ObjectId
    },
    { _id: false }
);

goalProgressSchema.set("toJSON", {
    virtuals: true,
    transform(_doc, obj: Record<string, any>) {
        const db = obj as IGoalProgressDatabase;
        const client = obj as IGoalProgressClient;

        client._id = toOid(db.goalId);

        delete obj.goalId;
        delete obj.__v;
    }
});

const pendingRecipeSchema = new Schema<IVaultPendingRecipeDatabase>(
    {
        ParentRoom: Types.ObjectId,
        ParentGuildId: Types.ObjectId,
        MiscItems: { type: [typeCountSchema], default: undefined },
        RegularCredits: Number,
        RushPlatinum: Number,
        CompletionTime: Date,
        Type: String,
        RecipeType: String
    },
    { _id: false }
);

const guildSchema = new Schema<IGuildDatabase>(
    {
        // SNS guild cheats
        noDojoRoomBuildStage: Boolean,
        noDojoDecoBuildStage: Boolean,
        fastDojoRoomDestruction: Boolean,
        noDojoResearchCosts: Boolean,
        noDojoResearchTime: Boolean,
        fastClanAscension: Boolean,

        Name: { type: String, required: true, unique: true },
        MOTD: { type: String, default: "" },
        LongMOTD: { type: longMOTDSchema, default: undefined },
        Ranks: { type: [guildRankSchema], default: defaultRanks },
        TradeTax: { type: Number, default: 0 },
        Tier: { type: Number, default: 1 },
        GuildTierIncMoratorium: Date,
        Emblem: Boolean,
        AutoContributeFromVault: Boolean,
        AllianceId: Types.ObjectId,
        Featured: Boolean,

        DojoComponents: { type: [dojoComponentSchema], default: [] },
        DojoCapacity: { type: Number, default: 100 },
        DojoEnergy: { type: Number, default: 5 },
        VaultRegularCredits: Number,
        VaultPremiumCredits: Number,
        VaultMiscItems: { type: [typeCountSchema], default: undefined },
        VaultShipDecorations: { type: [typeCountSchema], default: undefined },
        VaultFusionTreasures: { type: [fusionTreasuresSchema], default: undefined },
        VaultDecoRecipes: { type: [typeCountSchema], default: undefined },
        VaultRecipes: { type: [typeCountSchema], default: undefined },
        VaultInventoryItems: { type: [typeCountSchema], default: undefined },
        VaultPendingRecipes: { type: [pendingRecipeSchema], default: undefined },
        MaxBattlePayReserve: Number,
        MaxMissionBattlePay: Number,
        MinMissionBattlePay: Number,
        TechProjects: { type: [techProjectSchema], default: undefined },
        ActiveDojoColorResearch: { type: String, default: "" },
        Class: { type: Number, default: 0 },
        XP: { type: Number, default: 0 },
        ClaimedXP: { type: [String], default: undefined },
        CeremonyClass: Number,
        CeremonyContributors: { type: [Types.ObjectId], default: undefined },
        CeremonyResetDate: Date,
        CeremonyEndo: Number,
        RoomChanges: { type: [guildLogRoomChangeSchema], default: undefined },
        TechChanges: { type: [guildLogEntryContributableSchema], default: undefined },
        RosterActivity: { type: [guildLogEntryRosterSchema], default: undefined },
        ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined },
        GoalProgress: { type: [goalProgressSchema], default: undefined }
    },
    { id: false }
);

type GuildDocumentProps = {
    DojoComponents: Types.DocumentArray<IDojoComponentDatabase>;
};

type GuildModel = Model<IGuildDatabase, {}, GuildDocumentProps>;

export const Guild = model<IGuildDatabase, GuildModel>("Guild", guildSchema);

export type TGuildDatabaseDocument = Document<unknown, {}, IGuildDatabase> &
    Omit<
        IGuildDatabase & {
            _id: Types.ObjectId;
        } & {
            __v: number;
        },
        keyof GuildDocumentProps
    > &
    GuildDocumentProps;

const guildMemberSchema = new Schema<IGuildMemberDatabase>({
    accountId: Types.ObjectId,
    guildId: Types.ObjectId,
    status: { type: Number, required: true },
    rank: { type: Number, default: 7 },
    RequestMsg: String,
    RequestExpiry: Date,
    RegularCreditsContributed: Number,
    PremiumCreditsContributed: Number,
    MiscItemsContributed: { type: [typeCountSchema], default: undefined },
    ShipDecorationsContributed: { type: [typeCountSchema], default: undefined }
});

guildMemberSchema.index({ accountId: 1, guildId: 1 }, { unique: true });
guildMemberSchema.index({ RequestExpiry: 1 }, { expireAfterSeconds: 0 });

export const GuildMember = model<IGuildMemberDatabase>("GuildMember", guildMemberSchema);

export type TGuildMemberDatabaseDocument = Document<unknown, {}, IGuildMemberDatabase> &
    IGuildMemberDatabase & {
        _id: Types.ObjectId;
        __v: number;
    };

const guildAdSchema = new Schema<IGuildAdDatabase>({
    GuildId: { type: Schema.Types.ObjectId, required: true },
    Emblem: Boolean,
    Expiry: { type: Date, required: true },
    Features: { type: Number, required: true },
    GuildName: { type: String, required: true },
    MemberCount: { type: Number, required: true },
    RecruitMsg: { type: String, required: true },
    Tier: { type: Number, required: true }
});

guildAdSchema.index({ GuildId: 1 }, { unique: true });
guildAdSchema.index({ Expiry: 1 }, { expireAfterSeconds: 0 });

export const GuildAd = model<IGuildAdDatabase>("GuildAd", guildAdSchema);

const allianceSchema = new Schema<IAllianceDatabase>({
    Name: String,
    MOTD: longMOTDSchema,
    LongMOTD: longMOTDSchema,
    Emblem: Boolean,
    VaultRegularCredits: Number,
    VaultPremiumCredits: Number,
    VaultRecipes: { type: [typeCountSchema], default: undefined },
    VaultMiscItems: { type: [typeCountSchema], default: undefined },
    VaultInventoryItems: { type: [typeCountSchema], default: undefined },
    VaultPendingRecipes: { type: [pendingRecipeSchema], default: undefined },
    MaxBattlePayReserve: Number,
    MaxMissionBattlePay: Number,
    MinMissionBattlePay: Number
});

allianceSchema.index({ Name: 1 }, { unique: true });

type AllianceModel = Model<IAllianceDatabase>;

export const Alliance = model<IAllianceDatabase, AllianceModel>("Alliance", allianceSchema);

export type TAllianceDatabaseDocument = Document<unknown, {}, IAllianceDatabase> &
    IAllianceDatabase & {
        _id: Types.ObjectId;
        __v: number;
    };

const allianceMemberSchema = new Schema<IAllianceMemberDatabase>({
    allianceId: { type: Schema.Types.ObjectId, required: true },
    guildId: { type: Schema.Types.ObjectId, required: true },
    Pending: { type: Boolean, required: true },
    Permissions: { type: Number, required: true }
});

allianceMemberSchema.index({ allianceId: 1, guildId: 1 }, { unique: true });

export const AllianceMember = model<IAllianceMemberDatabase>("AllianceMember", allianceMemberSchema);