feat: guild ads #1390
							
								
								
									
										20
									
								
								src/controllers/api/cancelGuildAdvertisementController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/controllers/api/cancelGuildAdvertisementController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
import { GuildAd } from "@/src/models/guildModel";
 | 
			
		||||
import { getGuildForRequestEx, hasGuildPermission } from "@/src/services/guildService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { GuildPermission } from "@/src/types/guildTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const cancelGuildAdvertisementController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId, "GuildId");
 | 
			
		||||
    const guild = await getGuildForRequestEx(req, inventory);
 | 
			
		||||
    if (!(await hasGuildPermission(guild, accountId, GuildPermission.Advertiser))) {
 | 
			
		||||
        res.status(400).end();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    await GuildAd.deleteOne({ GuildId: guild._id });
 | 
			
		||||
 | 
			
		||||
    res.end();
 | 
			
		||||
};
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import { GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import {
 | 
			
		||||
    addGuildMemberMiscItemContribution,
 | 
			
		||||
    getDojoClient,
 | 
			
		||||
    getGuildForRequestEx,
 | 
			
		||||
    hasAccessToDojo,
 | 
			
		||||
@ -143,8 +144,7 @@ const processContribution = (
 | 
			
		||||
                ItemCount: ingredientContribution.ItemCount * -1
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            guildMember.MiscItemsContributed ??= [];
 | 
			
		||||
            guildMember.MiscItemsContributed.push(ingredientContribution);
 | 
			
		||||
            addGuildMemberMiscItemContribution(guildMember, ingredientContribution);
 | 
			
		||||
        }
 | 
			
		||||
        addMiscItems(inventory, miscItemChanges);
 | 
			
		||||
        inventoryChanges.MiscItems = miscItemChanges;
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,9 @@
 | 
			
		||||
import { GuildMember } from "@/src/models/guildModel";
 | 
			
		||||
import { addVaultMiscItems, getGuildForRequestEx } from "@/src/services/guildService";
 | 
			
		||||
import {
 | 
			
		||||
    addGuildMemberMiscItemContribution,
 | 
			
		||||
    addVaultMiscItems,
 | 
			
		||||
    getGuildForRequestEx
 | 
			
		||||
} from "@/src/services/guildService";
 | 
			
		||||
import { addFusionTreasures, addMiscItems, addShipDecorations, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { IFusionTreasure, IMiscItem, ITypeCount } from "@/src/types/inventoryTypes/inventoryTypes";
 | 
			
		||||
@ -25,14 +29,8 @@ export const contributeToVaultController: RequestHandler = async (req, res) => {
 | 
			
		||||
    if (request.MiscItems.length) {
 | 
			
		||||
        addVaultMiscItems(guild, request.MiscItems);
 | 
			
		||||
 | 
			
		||||
        guildMember.MiscItemsContributed ??= [];
 | 
			
		||||
        for (const item of request.MiscItems) {
 | 
			
		||||
            const miscItemContribution = guildMember.MiscItemsContributed.find(x => x.ItemType == item.ItemType);
 | 
			
		||||
            if (miscItemContribution) {
 | 
			
		||||
                miscItemContribution.ItemCount += item.ItemCount;
 | 
			
		||||
            } else {
 | 
			
		||||
                guildMember.MiscItemsContributed.push(item);
 | 
			
		||||
            }
 | 
			
		||||
            addGuildMemberMiscItemContribution(guildMember, item);
 | 
			
		||||
 | 
			
		||||
            addMiscItems(inventory, [{ ...item, ItemCount: item.ItemCount * -1 }]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
import {
 | 
			
		||||
    addGuildMemberMiscItemContribution,
 | 
			
		||||
    getGuildForRequestEx,
 | 
			
		||||
    getGuildVault,
 | 
			
		||||
    hasAccessToDojo,
 | 
			
		||||
@ -146,8 +147,7 @@ export const guildTechController: RequestHandler = async (req, res) => {
 | 
			
		||||
                    ItemCount: miscItem.ItemCount * -1
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                guildMember.MiscItemsContributed ??= [];
 | 
			
		||||
                guildMember.MiscItemsContributed.push(miscItem);
 | 
			
		||||
                addGuildMemberMiscItemContribution(guildMember, miscItem);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        addMiscItems(inventory, miscItemChanges);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										75
									
								
								src/controllers/api/postGuildAdvertisementController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/controllers/api/postGuildAdvertisementController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
			
		||||
import { getJSONfromString } from "@/src/helpers/stringHelpers";
 | 
			
		||||
import { GuildAd, GuildMember } from "@/src/models/guildModel";
 | 
			
		||||
import {
 | 
			
		||||
    addGuildMemberMiscItemContribution,
 | 
			
		||||
    addVaultMiscItems,
 | 
			
		||||
    getGuildForRequestEx,
 | 
			
		||||
    getVaultMiscItemCount,
 | 
			
		||||
    hasGuildPermissionEx
 | 
			
		||||
} from "@/src/services/guildService";
 | 
			
		||||
import { getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { getVendorManifestByTypeName, preprocessVendorManifest } from "@/src/services/serversideVendorsService";
 | 
			
		||||
import { GuildPermission } from "@/src/types/guildTypes";
 | 
			
		||||
import { IPurchaseParams } from "@/src/types/purchaseTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const postGuildAdvertisementController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const accountId = await getAccountIdForRequest(req);
 | 
			
		||||
    const inventory = await getInventory(accountId, "GuildId MiscItems");
 | 
			
		||||
    const guild = await getGuildForRequestEx(req, inventory);
 | 
			
		||||
    const guildMember = (await GuildMember.findOne({ accountId, guildId: guild._id }))!;
 | 
			
		||||
    if (!hasGuildPermissionEx(guild, guildMember, GuildPermission.Advertiser)) {
 | 
			
		||||
        res.status(400).end();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    const payload = getJSONfromString<IPostGuildAdvertisementRequest>(String(req.body));
 | 
			
		||||
 | 
			
		||||
    // Handle resource cost
 | 
			
		||||
    const vendor = preprocessVendorManifest(
 | 
			
		||||
        getVendorManifestByTypeName("/Lotus/Types/Game/VendorManifests/Hubs/GuildAdvertisementVendorManifest")!
 | 
			
		||||
    );
 | 
			
		||||
    const offer = vendor.VendorInfo.ItemManifest.find(x => x.StoreItem == payload.PurchaseParams.StoreItem)!;
 | 
			
		||||
    if (getVaultMiscItemCount(guild, offer.ItemPrices![0].ItemType) >= offer.ItemPrices![0].ItemCount) {
 | 
			
		||||
        addVaultMiscItems(guild, [
 | 
			
		||||
            {
 | 
			
		||||
                ItemType: offer.ItemPrices![0].ItemType,
 | 
			
		||||
                ItemCount: offer.ItemPrices![0].ItemCount * -1
 | 
			
		||||
            }
 | 
			
		||||
        ]);
 | 
			
		||||
    } else {
 | 
			
		||||
        const miscItem = inventory.MiscItems.find(x => x.ItemType == offer.ItemPrices![0].ItemType);
 | 
			
		||||
        if (!miscItem || miscItem.ItemCount < offer.ItemPrices![0].ItemCount) {
 | 
			
		||||
            res.status(400).json("Insufficient funds");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        miscItem.ItemCount -= offer.ItemPrices![0].ItemCount;
 | 
			
		||||
        addGuildMemberMiscItemContribution(guildMember, offer.ItemPrices![0]);
 | 
			
		||||
        await guildMember.save();
 | 
			
		||||
        await inventory.save();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create or update ad
 | 
			
		||||
    await GuildAd.findOneAndUpdate(
 | 
			
		||||
        { GuildId: guild._id },
 | 
			
		||||
        {
 | 
			
		||||
            Emblem: guild.Emblem,
 | 
			
		||||
            Expiry: new Date(Date.now() + 12 * 3600 * 1000),
 | 
			
		||||
            Features: payload.Features,
 | 
			
		||||
            GuildName: guild.Name,
 | 
			
		||||
            MemberCount: await GuildMember.countDocuments({ guildId: guild._id, status: 0 }),
 | 
			
		||||
            RecruitMsg: payload.RecruitMsg,
 | 
			
		||||
            Tier: guild.Tier
 | 
			
		||||
        },
 | 
			
		||||
        { upsert: true }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    res.end();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
interface IPostGuildAdvertisementRequest {
 | 
			
		||||
    Features: number;
 | 
			
		||||
    RecruitMsg: string;
 | 
			
		||||
    Languages: string[];
 | 
			
		||||
    PurchaseParams: IPurchaseParams;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										26
									
								
								src/controllers/dynamic/getGuildAdsController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/controllers/dynamic/getGuildAdsController.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
import { toMongoDate, toOid } from "@/src/helpers/inventoryHelpers";
 | 
			
		||||
import { GuildAd } from "@/src/models/guildModel";
 | 
			
		||||
import { IGuildAdInfoClient } from "@/src/types/guildTypes";
 | 
			
		||||
import { RequestHandler } from "express";
 | 
			
		||||
 | 
			
		||||
export const getGuildAdsController: RequestHandler = async (req, res) => {
 | 
			
		||||
    const ads = await GuildAd.find(req.query.tier ? { Tier: req.query.tier } : {});
 | 
			
		||||
    const guildAdInfos: IGuildAdInfoClient[] = [];
 | 
			
		||||
    for (const ad of ads) {
 | 
			
		||||
        guildAdInfos.push({
 | 
			
		||||
            _id: toOid(ad.GuildId),
 | 
			
		||||
            CrossPlatformEnabled: true,
 | 
			
		||||
            Emblem: ad.Emblem,
 | 
			
		||||
            Expiry: toMongoDate(ad.Expiry),
 | 
			
		||||
            Features: ad.Features,
 | 
			
		||||
            GuildName: ad.GuildName,
 | 
			
		||||
            MemberCount: ad.MemberCount,
 | 
			
		||||
            OriginalPlatform: 0,
 | 
			
		||||
            RecruitMsg: ad.RecruitMsg,
 | 
			
		||||
            Tier: ad.Tier
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    res.json({
 | 
			
		||||
        GuildAdInfos: guildAdInfos
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
@ -10,7 +10,8 @@ import {
 | 
			
		||||
    IGuildLogRoomChange,
 | 
			
		||||
    IGuildLogEntryRoster,
 | 
			
		||||
    IGuildLogEntryContributable,
 | 
			
		||||
    IDojoLeaderboardEntry
 | 
			
		||||
    IDojoLeaderboardEntry,
 | 
			
		||||
    IGuildAdDatabase
 | 
			
		||||
} from "@/src/types/guildTypes";
 | 
			
		||||
import { Document, Model, model, Schema, Types } from "mongoose";
 | 
			
		||||
import { fusionTreasuresSchema, typeCountSchema } from "./inventoryModels/inventoryModel";
 | 
			
		||||
@ -165,6 +166,7 @@ const guildSchema = new Schema<IGuildDatabase>(
 | 
			
		||||
        Ranks: { type: [guildRankSchema], default: defaultRanks },
 | 
			
		||||
        TradeTax: { type: Number, default: 0 },
 | 
			
		||||
        Tier: { type: Number, default: 1 },
 | 
			
		||||
        Emblem: { type: Boolean },
 | 
			
		||||
        DojoComponents: { type: [dojoComponentSchema], default: [] },
 | 
			
		||||
        DojoCapacity: { type: Number, default: 100 },
 | 
			
		||||
        DojoEnergy: { type: Number, default: 5 },
 | 
			
		||||
@ -225,3 +227,19 @@ const guildMemberSchema = new Schema<IGuildMemberDatabase>({
 | 
			
		||||
guildMemberSchema.index({ accountId: 1, guildId: 1 }, { unique: true });
 | 
			
		||||
 | 
			
		||||
export const GuildMember = model<IGuildMemberDatabase>("GuildMember", guildMemberSchema);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@ import { arcaneCommonController } from "@/src/controllers/api/arcaneCommonContro
 | 
			
		||||
import { archonFusionController } from "@/src/controllers/api/archonFusionController";
 | 
			
		||||
import { artifactsController } from "@/src/controllers/api/artifactsController";
 | 
			
		||||
import { artifactTransmutationController } from "@/src/controllers/api/artifactTransmutationController";
 | 
			
		||||
import { cancelGuildAdvertisementController } from "@/src/controllers/api/cancelGuildAdvertisementController";
 | 
			
		||||
import { changeDojoRootController } from "@/src/controllers/api/changeDojoRootController";
 | 
			
		||||
import { changeGuildRankController } from "@/src/controllers/api/changeGuildRankController";
 | 
			
		||||
import { checkDailyMissionBonusController } from "@/src/controllers/api/checkDailyMissionBonusController";
 | 
			
		||||
@ -80,6 +81,7 @@ import { nameWeaponController } from "@/src/controllers/api/nameWeaponController
 | 
			
		||||
import { nemesisController } from "@/src/controllers/api/nemesisController";
 | 
			
		||||
import { placeDecoInComponentController } from "@/src/controllers/api/placeDecoInComponentController";
 | 
			
		||||
import { playerSkillsController } from "@/src/controllers/api/playerSkillsController";
 | 
			
		||||
import { postGuildAdvertisementController } from "@/src/controllers/api/postGuildAdvertisementController";
 | 
			
		||||
import { projectionManagerController } from "@/src/controllers/api/projectionManagerController";
 | 
			
		||||
import { purchaseController } from "@/src/controllers/api/purchaseController";
 | 
			
		||||
import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController";
 | 
			
		||||
@ -131,6 +133,7 @@ const apiRouter = express.Router();
 | 
			
		||||
// get
 | 
			
		||||
apiRouter.get("/abandonLibraryDailyTask.php", abandonLibraryDailyTaskController);
 | 
			
		||||
apiRouter.get("/abortDojoComponentDestruction.php", abortDojoComponentDestructionController);
 | 
			
		||||
apiRouter.get("/cancelGuildAdvertisement.php", cancelGuildAdvertisementController);
 | 
			
		||||
apiRouter.get("/changeGuildRank.php", changeGuildRankController);
 | 
			
		||||
apiRouter.get("/checkDailyMissionBonus.php", checkDailyMissionBonusController);
 | 
			
		||||
apiRouter.get("/claimLibraryDailyTaskReward.php", claimLibraryDailyTaskRewardController);
 | 
			
		||||
@ -228,6 +231,7 @@ apiRouter.post("/nameWeapon.php", nameWeaponController);
 | 
			
		||||
apiRouter.post("/nemesis.php", nemesisController);
 | 
			
		||||
apiRouter.post("/placeDecoInComponent.php", placeDecoInComponentController);
 | 
			
		||||
apiRouter.post("/playerSkills.php", playerSkillsController);
 | 
			
		||||
apiRouter.post("/postGuildAdvertisement.php", postGuildAdvertisementController);
 | 
			
		||||
apiRouter.post("/projectionManager.php", projectionManagerController);
 | 
			
		||||
apiRouter.post("/purchase.php", purchaseController);
 | 
			
		||||
apiRouter.post("/redeemPromoCode.php", redeemPromoCodeController);
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,13 @@
 | 
			
		||||
import express from "express";
 | 
			
		||||
import { aggregateSessionsController } from "@/src/controllers/dynamic/aggregateSessionsController";
 | 
			
		||||
import { getGuildAdsController } from "@/src/controllers/dynamic/getGuildAdsController";
 | 
			
		||||
import { getProfileViewingDataController } from "@/src/controllers/dynamic/getProfileViewingDataController";
 | 
			
		||||
import { worldStateController } from "@/src/controllers/dynamic/worldStateController";
 | 
			
		||||
 | 
			
		||||
const dynamicController = express.Router();
 | 
			
		||||
 | 
			
		||||
dynamicController.get("/aggregateSessions.php", aggregateSessionsController);
 | 
			
		||||
dynamicController.get("/getGuildAds.php", getGuildAdsController);
 | 
			
		||||
dynamicController.get("/getProfileViewingData.php", getProfileViewingDataController);
 | 
			
		||||
dynamicController.get("/worldState.php", worldStateController);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { Request } from "express";
 | 
			
		||||
import { getAccountIdForRequest } from "@/src/services/loginService";
 | 
			
		||||
import { addRecipes, getInventory } from "@/src/services/inventoryService";
 | 
			
		||||
import { Guild, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { Guild, GuildAd, GuildMember, TGuildDatabaseDocument } from "@/src/models/guildModel";
 | 
			
		||||
import { TInventoryDatabaseDocument } from "@/src/models/inventoryModels/inventoryModel";
 | 
			
		||||
import {
 | 
			
		||||
    GuildPermission,
 | 
			
		||||
@ -298,6 +298,10 @@ const moveResourcesToVault = (guild: TGuildDatabaseDocument, component: IDojoCon
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const getVaultMiscItemCount = (guild: TGuildDatabaseDocument, itemType: string): number => {
 | 
			
		||||
    return guild.VaultMiscItems?.find(x => x.ItemType == itemType)?.ItemCount ?? 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const addVaultMiscItems = (guild: TGuildDatabaseDocument, miscItems: ITypeCount[]): void => {
 | 
			
		||||
    guild.VaultMiscItems ??= [];
 | 
			
		||||
    for (const miscItem of miscItems) {
 | 
			
		||||
@ -310,6 +314,16 @@ export const addVaultMiscItems = (guild: TGuildDatabaseDocument, miscItems: ITyp
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const addGuildMemberMiscItemContribution = (guildMember: IGuildMemberDatabase, item: ITypeCount): void => {
 | 
			
		||||
    guildMember.MiscItemsContributed ??= [];
 | 
			
		||||
    const miscItemContribution = guildMember.MiscItemsContributed.find(x => x.ItemType == item.ItemType);
 | 
			
		||||
    if (miscItemContribution) {
 | 
			
		||||
        miscItemContribution.ItemCount += item.ItemCount;
 | 
			
		||||
    } else {
 | 
			
		||||
        guildMember.MiscItemsContributed.push(item);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const processDojoBuildMaterialsGathered = (guild: TGuildDatabaseDocument, build: IDojoBuild): void => {
 | 
			
		||||
    if (build.guildXpValue) {
 | 
			
		||||
        guild.ClaimedXP ??= [];
 | 
			
		||||
@ -513,4 +527,6 @@ export const deleteGuild = async (guildId: Types.ObjectId): Promise<void> => {
 | 
			
		||||
        contextInfo: guildId.toString(),
 | 
			
		||||
        acceptAction: "GUILD_INVITE"
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    await GuildAd.deleteOne({ GuildId: guildId });
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@ export interface IGuildDatabase {
 | 
			
		||||
    Ranks: IGuildRank[];
 | 
			
		||||
    TradeTax: number;
 | 
			
		||||
    Tier: number;
 | 
			
		||||
    Emblem?: boolean;
 | 
			
		||||
 | 
			
		||||
    DojoComponents: IDojoComponentDatabase[];
 | 
			
		||||
    DojoCapacity: number;
 | 
			
		||||
@ -223,3 +224,27 @@ export interface IDojoLeaderboardEntry {
 | 
			
		||||
    r: number; // rank
 | 
			
		||||
    n: string; // displayName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IGuildAdInfoClient {
 | 
			
		||||
    _id: IOid; // Guild ID
 | 
			
		||||
    CrossPlatformEnabled: boolean;
 | 
			
		||||
    Emblem?: boolean;
 | 
			
		||||
    Expiry: IMongoDate;
 | 
			
		||||
    Features: number;
 | 
			
		||||
    GuildName: string;
 | 
			
		||||
    MemberCount: number;
 | 
			
		||||
    OriginalPlatform: number;
 | 
			
		||||
    RecruitMsg: string;
 | 
			
		||||
    Tier: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IGuildAdDatabase {
 | 
			
		||||
    GuildId: Types.ObjectId;
 | 
			
		||||
    Emblem?: boolean;
 | 
			
		||||
    Expiry: Date;
 | 
			
		||||
    Features: number;
 | 
			
		||||
    GuildName: string;
 | 
			
		||||
    MemberCount: number;
 | 
			
		||||
    RecruitMsg: string;
 | 
			
		||||
    Tier: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user