diff --git a/plugins/userbg/manifest.json b/plugins/userbg/manifest.json
new file mode 100644
index 0000000..e4c9253
--- /dev/null
+++ b/plugins/userbg/manifest.json
@@ -0,0 +1,18 @@
+{
+ "name": "UserBG",
+ "description": "https://github.com/Discord-Custom-Covers/usrbg#request-your-own-usrbg",
+ "authors": [
+ {
+ "name": "sapphire",
+ "id": "757982547861962752"
+ },
+ {
+ "name": "Rico040",
+ "id": "619474349845643275"
+ }
+ ],
+ "main": "src/index.tsx",
+ "vendetta": {
+ "icon": "ic_profile_24px"
+ }
+}
\ No newline at end of file
diff --git a/plugins/userbg/src/Settings.tsx b/plugins/userbg/src/Settings.tsx
new file mode 100644
index 0000000..2a91c04
--- /dev/null
+++ b/plugins/userbg/src/Settings.tsx
@@ -0,0 +1,29 @@
+import { React, url } from "@vendetta/metro/common"
+import { getAssetIDByName } from "@vendetta/ui/assets"
+import { Forms, General } from "@vendetta/ui/components"
+import { showToast } from "@vendetta/ui/toasts"
+
+import { fetchData } from "./index"
+
+const { ScrollView } = General
+const { FormSection, FormRow } = Forms
+
+export default () => (
+
+ }
+ trailing={FormRow.Arrow}
+ onPress={() => url.openDeeplink("https://discord.gg/TeRQEPb")}
+ />
+ }
+ onPress={async () => {
+ const fetch = await fetchData()
+ if (!fetch) return showToast("Failed to reload DB", getAssetIDByName("small"))
+ return showToast("Reloaded DB", getAssetIDByName("check"))
+ }}
+ />
+
+)
\ No newline at end of file
diff --git a/plugins/userbg/src/index.tsx b/plugins/userbg/src/index.tsx
new file mode 100644
index 0000000..fe0e1e2
--- /dev/null
+++ b/plugins/userbg/src/index.tsx
@@ -0,0 +1,45 @@
+import { logger } from "@vendetta"
+import { findByProps } from "@vendetta/metro"
+import { after } from "@vendetta/patcher"
+import { safeFetch } from "@vendetta/utils"
+import { showToast } from "@vendetta/ui/toasts"
+
+import Settings from "./Settings"
+
+interface userBGData {
+ endpoint: string;
+ bucket: string;
+ prefix: string;
+ users: Record;
+}
+
+const getUserBannerURL = findByProps("default", "getUserBannerURL")
+
+let data: userBGData
+let unpatch: () => void
+
+export const fetchData = async () => {
+ try {
+ data = await (await safeFetch("https://usrbg.is-hardly.online/users", { cache: "no-store" })).json()
+ return data
+ } catch (e) {
+ logger.error("Failed to fetch userBG data", e)
+ }
+}
+
+export const onLoad = async () => {
+ await fetchData()
+ if (!data) return showToast("Failed to load DB")
+ const { endpoint, bucket, prefix, users } = data;
+ unpatch = after("getUserBannerURL", getUserBannerURL, ([user]) => {
+ const customBanner = Object.entries(users).find(([userId, etag]) => userId === user?.id)
+ if (user?.banner === undefined && customBanner) {
+ const [userId, etag] = customBanner;
+ return `${endpoint}/${bucket}/${prefix}${userId}?${etag}`
+ }
+ })
+}
+
+export const onUnload = () => unpatch?.()
+
+export const settings = Settings
\ No newline at end of file