feat: 🎸 使用本地设置生成提示词

dev
杨晓宇 3 years ago
parent a81dfcb876
commit b2fbfb9d89

@ -1,27 +1,333 @@
import { PromptToken } from "types"; import { Keyword } from "types";
/** 字典 */ /** 字典 */
export const PROMPT_DICT: { export const PROMPT_DICT: {
[part: string]: PromptToken[]; [part: string]: Keyword[];
} = { } = {
test: [ test: [
{ value: "黑长直", class: "adj" }, {
{ value: "电波系", class: "adj" }, value: "黑长直",
{ value: "伪娘", class: "n" }, class: "adj",
{ value: "兔女郎", class: "adj" }, prompts: {
{ value: "傲娇", class: "adj" }, base: ["Flowing tresses", "Sleek and straight strands"],
{ value: "病娇", class: "adj" }, hairColor: "Glossy black hair",
{ value: "天然呆", class: "adj" }, },
{ value: "活力", class: "adj" }, },
{ value: "抖S", class: "adj" }, {
{ value: "抖M", class: "adj" }, value: "伪娘",
{ value: "三无", class: "adj" }, class: "n",
{ value: "泳装", class: "adj" }, prompts: {
{ value: "银发", class: "adj" }, base: [
{ value: "女仆", class: "n" }, "Feminine appearance",
{ value: "美少女", class: "n" }, "Cute outfit",
{ value: "御姐", class: "n" }, "Shimmering eyeshadow",
{ value: "萝莉", class: "n" }, "High heeled shoes",
"Flawless skin",
"Feminine accessories",
"Graceful posture",
"Sweet smile",
"Playful demeanor",
"Girly charm",
],
},
},
{
value: "兔女郎",
class: "adj",
prompts: {
base: [
"Bunny girl",
"Rabbit ears",
"Cute",
"Playful",
"Sexy",
"Fluffy tail",
"Carrots",
"Easter",
"Pink",
"Thigh-high stockings",
"Bow tie",
"Curvy",
"Innocent",
"Sassy",
"Furry",
"Lustrous hair",
"Playmate",
],
},
},
{
value: "傲娇",
class: "adj",
prompts: {
base: [
"Arrogant",
"Cocky",
"Self-important",
"Self-centered",
"Narcissistic",
"Insolent",
"Condescending",
"Contemptuous",
],
},
},
{
value: "病娇",
class: "adj",
prompts: {
base: [
"Cutesy yet dangerous",
"Obsessive behavior",
"Innocent appearance with sinister undertones",
"Unstable emotions and mood swings",
"Lovesick and possessive",
"Clingy and needy",
"Outwardly sweet but inwardly devious",
"Intense and volatile personality",
"Can be manipulative and controlling",
"Dark and troubled past",
"Fragile and vulnerable",
"Plays the victim card",
"A mix of sweetness and insanity",
"Hard to resist but dangerous to cross",
"Demanding and high-maintenance",
"Perpetually in a state of emotional turmoil",
"Possesses a hidden dark side",
"Resistant to change and easily offended",
"Can be both alluring and terrifying at the same time",
],
},
},
{
value: "天然呆",
class: "adj",
prompts: {
base: [
"Adorkable",
"Innocent",
"Simple",
"Naive",
"Untainted",
" Quirky ",
" Unassuming ",
" Unsophisticated ",
" Endearing ",
" Sweet ",
" Charming ",
" Innocuous ",
" Childlike ",
" Nurturing ",
" Trusting ",
" Genuine ",
" Unpretentious ",
" Candid ",
" Artless ",
" Pure",
],
},
},
{
value: "抖S",
class: "adj",
prompts: {
base: [
" Whips",
" Dominatrix",
" Leather",
" Corsets",
" Chains",
" Risky behavior",
" Control",
" Submission",
" Spanking",
" Collars",
" Bondage",
" Black latex gloves",
" Safe words",
" Riding crop",
" Discipline",
" Pain",
" Pleasure",
" Body harness",
" Role playing",
" Power exchange",
],
},
},
{
value: "抖M",
class: "adj",
prompts: {
base: [
" Masochistic tendencies",
" Whips and chains",
" Submission",
" Punishment",
" Humiliation",
" Sadomasochism",
" Dominance",
" Role play",
" Bondage",
" Leather gear",
" Safeword",
" Power exchange",
" Consensual non-consent",
" Degradation",
" Foot worship",
" Cuffs and restraints",
" Impact play",
" Verbal humiliation",
" Chastity",
" Teasing and denial",
],
},
},
{
value: "泳装",
class: "adj",
prompts: {
base: [
" Beachwear ",
" Swimsuit ",
" Beach hat ",
" Sunglasses ",
" Sunscreen ",
" Bikini ",
" Poolside ",
" Water sports ",
" Sun-kissed ",
" Tanned skin ",
" Sun hat ",
" Beach bag ",
" Flip-flops ",
" Beach towel ",
" Ocean waves ",
" Board shorts ",
" Surfer girl ",
" Palm trees ",
" Sea shells ",
" Tropical paradise",
],
},
},
{
value: "银发",
class: "adj",
prompts: {
base: [
" Silver hair",
" Elderly person",
" Wise",
" Sophisticated",
" Grandparent",
" Dignified",
" Graceful",
" Experienced",
" Serene",
" Timeless",
" Refined",
" Regal",
" Elegant",
" Respected",
" Majestic",
" Honorable",
" Charismatic",
" Cultured",
" Prestigious",
" Noble",
],
},
},
{
value: "女仆",
class: "n",
prompts: {
base: [
" Maid costume",
" Serving tray",
" Feather duster",
" Bows and ribbons",
" Clean and tidy",
" Apron",
" High heels",
" Polite and respectful",
" Uniform",
" Updo hairstyle",
" Mistress or master",
" Tea set",
" Pinafore dress",
" Chores and tasks",
" Maid headband",
" Lace or frills",
" Domestic service",
" Well-groomed appearance",
" Submissive demeanor",
" Tidy and organized environment",
],
},
},
{
value: "美少女",
class: "n",
prompts: {
base: [
"Cute smile",
"Flowing dress",
"Rosy cheeks",
"Pink lips",
"Playful expression",
"Innocent blush",
"Elegant posture",
"Enchanting gaze",
"Delicate facial features",
"Graceful body language",
],
},
},
{
value: "御姐",
class: "n",
prompts: {
base: [
"Elegant",
"Confident",
"Seductive",
"Mysterious",
"Powerful",
"Regal",
"Graceful",
"Intimidating",
"Alluring",
"Sophisticated",
"Enigmatic",
"Enchanting",
"Imposing",
"Commanding",
"Glamorous",
"Queenly",
],
},
},
{
value: "萝莉",
class: "n",
prompts: {
base: [
"Innocent eyes",
"Petite stature",
"Blushing cheeks",
"Adorable smile",
"Cute bows",
"Vibrant colors",
"Playful expression",
"Over-sized hat",
"Flower headband",
"Candy-colored outfit",
"Plush toys",
],
},
},
], ],
}; };

@ -0,0 +1,218 @@
export const BODY_BREASTS = [
"breasts",
"small breasts",
"medium breasts",
"large breasts",
"huge breasts",
"alternate breast size",
"mole on breast",
"between breasts",
"breasts apart",
"hanging breasts",
"bouncing breasts",
];
export const BODY_CLOTHING = [
"sailor collar",
"hat",
"shirt",
"serafuku",
"sailor suite",
"sailor shirt",
"shorts under skirt",
"collared shirt",
"school uniform",
"seifuku",
"business_suit",
"jacket",
"suit",
"garreg mach monastery uniform",
"revealing dress",
"pink lucency full dress",
"cleavage dress",
"sleeveless dress",
"whitedress",
"wedding_dress",
"Sailor dress",
"sweater dress",
"ribbed sweater",
"sweater jacket",
"dungarees",
"brown cardigan",
"hoodie",
"robe",
"cape",
"cardigan",
"apron",
"gothic",
"lolita_fashion",
"gothic_lolita",
"western",
"tartan",
"off_shoulder",
"bare_shoulders",
"barefoot",
"bare_legs",
"striped",
"polka_dot",
"frills",
"lace",
"buruma",
"sportswear",
"gym_uniform",
"tank_top",
"cropped jacket",
"black sports bra",
"crop top",
"pajamas",
"japanese_clothes",
"obi",
"mesh",
"sleeveless shirt",
"detached_sleeves",
"white bloomers",
"high - waist shorts",
"pleated_skirt",
"skirt",
"miniskirt",
"short shorts",
"summer_dress",
"bloomers",
"shorts",
"bike_shorts",
"dolphin shorts",
"belt",
"bikini",
"sling bikini",
"bikini_top",
"bikini top only",
"side - tie bikini bottom",
"side-tie_bikini",
"friled bikini",
"bikini under clothes",
"swimsuit",
"school swimsuit",
"one-piece swimsuit",
"competition swimsuit",
"Sukumizu",
];
export const BODY_LEG_ORNAMENTS = [
"bare legs",
"garter straps",
"garter belt",
"socks",
"kneehighs",
"white kneehighs",
"black kneehighs",
"over-kneehighs",
"single kneehigh",
"tabi",
"bobby socks",
"loose socks",
"single sock",
"no socks",
"socks removed",
"ankle socks",
"striped socks",
"blue socks",
"grey socks",
"red socks",
"frilled socks",
"thighhighs",
"black thighhighs",
"white thighhighs",
"striped thighhighs",
"brown thighhighs",
"blue thighhighs",
"red thighhighs",
"purple thighhighs",
"pink thighhighs",
"grey thighhighs",
"thighhighs under boots",
"green thighhighs",
"yellow thighhighs",
"orange thighhighs",
"vertical-striped thighhighs",
"frilled thighhighs",
"fishnet thighhighs",
"pantyhose",
"black pantyhose",
"white pantyhose",
"thighband pantyhose",
"brown pantyhose",
"fishnet pantyhose",
"striped pantyhose",
"vertical-striped pantyhose",
"grey pantyhose",
"blue pantyhose",
"single leg pantyhose",
"purple pantyhose",
"red pantyhose",
"fishnet legwear",
"bandaged leg",
"bandaid on leg",
"mechanical legs",
"leg belt",
"leg tattoo",
"bound legs",
"leg lock",
"panties under pantyhose",
"panty",
"thighhighs over pantyhose",
"socks over thighhighs",
"panties over pantyhose",
"pantyhose under swimsuit",
"black garter belt",
"neck garter",
"white garter straps",
"black garter straps",
"ankle garter",
"no legwear",
"black legwear",
"white legwear",
"torn legwear",
"striped legwear",
"asymmetrical legwear",
"brown legwear",
"uneven legwear",
"toeless legwear",
"print legwear",
"lace-trimmed legwear",
"red legwear",
"mismatched legwear",
"legwear under shorts",
"purple legwear",
"grey legwear",
"blue legwear",
"pink legwear",
"argyle legwear",
"ribbon-trimmed legwear",
"american flag legwear",
"green legwear",
"vertical-striped legwear",
"frilled legwear",
"stirrup legwear",
"alternate legwear",
"seamed legwear",
"yellow legwear",
"multicolored legwear",
"ribbed legwear",
"fur-trimmed legwear",
"see-through legwear",
"legwear garter",
"two-tone legwear",
"latex legwear",
];
export const BODY_SHOES = [
"shoes",
"boots",
"loafers",
"high heels",
"cross-laced_footwear",
"mary_janes",
"uwabaki",
"slippers",
"knee_boots",
];

@ -0,0 +1,53 @@
export const ENVIRONMENT_TIME = [
"day",
"dusk",
"night",
"in spring",
"in summer",
"in autumn",
"in winter",
];
export const ENVIRONMENT_SKY = [
"sun",
"sunset",
"moon",
"full_moon",
"stars",
"cloudy",
"rain",
"in the rain",
"rainy days",
"snow",
];
export const ENVIRONMENT_LOCATION = [
"sky",
"sea",
"mountain",
"on a hill",
"the top of the hill",
"in a meadow",
"plateau",
"on a desert",
"in hawaii",
"cityscape",
"landscape",
"beautiful detailed sky",
"beautiful detailed water",
"on the beach",
"on the ocean",
"over the sea",
"beautiful purple sunset at beach",
"in the ocean",
"against backlight at dusk",
"golden hour lighting",
"strong rim light",
"intense shadows",
"fireworks",
"flower field",
"underwater",
"explosion",
"in the cyberpunk city",
"steam",
];

@ -0,0 +1,54 @@
export const EYE_COLOR = [
"blue eyes",
"red eyes",
"brown eyes",
"green eyes",
"purple eyes",
"yellow eyes",
"pink eyes",
"black eyes",
"aqua eyes",
"orange eyes",
"grey eyes",
"multicolored eyes",
"white eyes",
"gradient eyes",
];
export const EYE_STYLE = [
"eyeshadow",
"red eyeshadow",
"blue eyeshadow",
"purple eyeshadow",
"pink eyeshadow",
"green eyeshadow",
"bags under eyes",
"ringed eyes",
"covered eyes",
"covering eyes",
"shading eyes",
];
export const EYE_STATUS = [
"closed eyes",
"half-closed eyes",
"crying with eyes open",
"narrowed eyes",
"hidden eyes",
"heart-shaped eyes",
"button eyes",
"cephalopod eyes",
"eyes visible through hair",
"glowing eyes",
"empty eyes",
"rolling eyes",
"blank eyes",
"no eyes",
"sparkling eyes",
"extra eyes",
"crazy eyes",
"solid circle eyes",
"solid oval eyes",
"uneven eyes",
"blood from eyes",
];

@ -0,0 +1,92 @@
export const FACIAL_FEATURE = [
"food on face",
"light blush",
"facepaint",
"makeup",
"cute face",
"white colored eyelashes",
"longeyelashes",
"white eyebrows",
"tsurime",
"gradient",
"beautiful detailed eyes",
"tareme",
"slit pupils",
"heterochromia",
"heterochromia blue red",
"aqua eyes",
"looking at viewer",
"eyeball",
"stare",
"visible through hair",
"looking to the side",
"constricted pupils",
"symbol",
"heart in eye",
"heart",
"wink",
"mole under eye",
"eyes closed",
"no",
"fake animal ears",
"animal ear fluff",
"animal",
"fox",
"bunny",
"cat",
"dog",
"mouse",
"hair ear",
"pointy ears",
];
export const FACIAL_EXPRESSION = [
"light smile",
"seductive smile",
"grin",
"laughing",
"teeth",
"excited",
"embarrassed",
"blush",
"shy",
"nose blush",
"expressionless",
"expressionless eyes",
"sleepy",
"drunk",
"tears",
"crying with eyes open",
"sad",
"pout",
"sigh",
"wide eyed",
"angry",
"annoyed",
"frown",
"smirk",
"serious",
"jitome",
"scowl",
"crazy",
"dark",
"smirk",
"smug",
"naughty",
"one eye closed",
"half-closed eyes",
"nosebleed",
"eyelid pull",
"tongue",
"tongue out",
"closed mouth",
"open mouth",
"lipstick",
"fangs",
"clenched teeth",
":3",
":p",
":q",
":t",
":d",
];

@ -0,0 +1,226 @@
// 如需要更新词条,请访问 https://tools.miku.ac/novelai_tag/,并修改以下代码获取词条
// const labels = [];document.querySelectorAll("#pane-头发\\&发饰 > div:nth-child(1) > div.el-checkbox-group > label > span.el-checkbox__label").forEach(label=>labels.push(label.outerHTML.match(/\n(\s|\d|[a-zA-Z]|:|-|_)+/)[0].replace(/(\n|\s)+/,"").replace(/\s$/,"")));labels;
/** 通用特征 */
export const GENERAL_PROMPTS = {};
export const STYLE = [
"artbook",
"game_cg",
"comic",
"4koma",
"animated_gif gif",
"dakimakura",
"cosplay",
"crossover",
"dark",
"light",
"night",
"guro",
"realistic",
"photo",
"real",
"landscape",
"cityscape",
"science_fiction",
"original",
"parody",
"personification",
"checkered",
"lowres",
"highres",
"absurdres",
"incredibly_absurdres",
"huge_filesize",
"wallpaper",
"pixel_art",
"monochrome",
"colorful",
"optical_illusion",
"fine_art_parody",
"sketch",
"traditional_media",
"watercolor_",
"silhouette",
"covr",
"album",
"sample",
"back",
"bust",
"profile",
"expressions",
"everyone",
"column_lineup",
"transparent_background",
"simple_background",
"gradient_background",
"zoom_layer",
"English",
"Chinese",
"French",
"Japanese",
"translation_request",
"bad_id ID",
"tagme",
"artist_request",
"what",
];
export const CHARACTER = [
"1girl",
"2girls",
"3girls",
"1boy",
"2boys",
"3boys",
"solo",
"multiple girls",
"little girl",
"little boy",
"shota",
"loli",
"kawaii",
"mesugaki",
"adorable girl",
"bishoujo",
"gyaru",
"sisters",
"ojousama",
"mature female",
"mature",
"female pervert",
"milf",
"harem",
];
export const ROLE = [
"angel",
"cheerleader",
"chibi Q",
"crossdressing",
"devil",
"doll",
"elf",
"fairy",
"female",
"furry",
"orc",
"giantess",
"harem",
"idol",
"kemonomimi_mode",
"loli",
"magical_girl",
"maid",
"male",
"mermaid",
"miko",
"milf",
"minigirl",
"monster",
"multiple_girls",
"ninja",
"no_humans",
"nun",
"nurse",
"shota",
"stewardess",
"student",
"trap",
"vampire",
"waitress",
"witch",
"yaoi",
"yukkuri_shiteitte_ne",
"yuri",
];
export const ACTION = [
"head tilt",
"turning around",
"looking back",
"looking down",
"looking up",
"smelling",
"hand_to_mouth",
"arm at side",
"arms behind head",
"arms behind back",
"hand on own chest",
"arms_crossed",
"hand on hip",
"hand on another",
"hand_on_hip",
"hands_on_hips",
"arms up",
"hands up",
"stretch",
"armpits",
"leg hold",
"grabbing",
"holding",
"fingersmile",
"hair_pull",
"hair scrunchie",
"w",
"v",
"peace symbol",
"thumbs_up",
"middle_finger",
"cat_pose",
"finger_gun",
"shushing",
"waving",
"salute",
"spread_arms",
"spread legs",
"crossed_legs",
"fetal_position",
"leg_lift",
"legs_up",
"leaning forward",
"fetal position",
"against wall",
"on_stomach",
"squatting",
"lying",
"sitting",
"sitting on",
"seiza",
"wariza",
"yokozuwari",
"indian_style",
"leg_hug",
"walking",
"running",
"straddle",
"straddling",
"kneeling",
"smoking",
"arm_support",
"caramelldansen niconiconi",
"princess_carry",
"fighting_stance",
"upside-down",
"top-down_bottom-up",
"bent_over",
"arched_back",
"back-to-back",
"symmetrical_hand_pose",
"eye_contact",
"hug",
"lap_pillow",
"sleeping",
"bathing",
"mimikaki",
"holding_hands",
];
export const R18TAG = [
"surrounded, multiple others, exhibitionism, audience, background characters, crowd, public humiliation",
"partially unbuttoned",
"show foot",
"pubic tattoo on underbelly",
"spread pussy",
"ass_visible_through_thighs",
];

@ -0,0 +1,171 @@
/** 头发长度 */
export const HAIR_LENGTH = [
"very short hair",
"short hair",
"medium hair",
"long hair",
"very long hair",
"absurdly long hair",
"hair over shoulder",
"alternate hair length",
];
/** 发色 */
export const HAIR_COLOR = [
"blonde hair",
"brown hair",
"black hair",
"blue hair",
"purple hair",
"pink hair",
"white hair",
"red hair",
"grey hair",
"green hair",
"silver hair",
"orange hair",
"light brown hair",
"light purple hair",
"light blue hair",
"platinum blonde hair",
"gradient hair",
"multicolored hair",
"shiny hair",
"two",
"streaked hair",
"aqua hair",
"colored inner hair",
"alternate hair color",
"hair up",
"hair down",
"wet hair",
];
/** 发型特征 */
export const HAIR_STYLE = [
"ahoge",
"antenna hair",
"bob cut",
"hime_cut",
"crossed bangs",
"hair wings",
"disheveled hair",
"wavy hair",
"curly_hair",
"hair in takes",
"forehead",
"drill hair",
"hair bun",
"double",
"straight hair",
"spiked hair",
"short hair with long locks",
"low",
"asymmetrical hair",
"alternate hairstyle",
"big hair",
"hair strand",
"hair twirling",
"pointy hair",
"hair slicked back",
"hair pulled back",
"split",
];
/** 发辫 */
export const HAIR_BRAID = [
"braid",
"twin braids",
"single braid",
"side braid",
"long braid",
"french braid",
"crown braid",
"braided bun",
"ponytail",
"braided ponytail",
"high ponytail",
"twintails",
"short",
"twin",
"Side ponytail",
];
/** 刘海 */
export const HAIR_BANGS = [
"bangs",
"blunt bangs",
"parted bangs",
"swept bangs",
"crossed bangs",
"asymmetrical bangs",
"braided bangs",
"long bangs",
"bangs pinned back",
"diagonal bangs",
"dyed bangs",
"hair between eyes",
"hair over one eye",
"hair over eyes",
"hair behind ear",
"hair between breasts",
"hair over breasts",
"hair censor",
];
/** 发饰 */
export const HAIR_ORNAMENT = [
"hair ornament",
"hair bow",
"hair ribbon",
"hairband",
"hair flower",
"hair bun",
"hair bobbles",
"hairclip",
"single hair bun",
"x hair ornament x",
"black hairband",
"hair scrunchie",
"hair rings",
"tied hair",
"hairpin",
"white hairband",
"hair tie",
"frog hair ornament",
"food",
"tentacle hair",
"star hair ornament",
"hair bell",
"heart hair ornament",
"red hairband",
"butterfly hair ornament",
"hair stick",
"snake hair ornament",
"lolita hairband",
"crescent hair ornament",
"cone hair bun",
"feather hair ornament",
"blue hairband",
"anchor hair ornament",
"leaf hair ornament",
"bunny hair ornament",
"skull hair ornament",
"yellow hairband",
"pink hairband",
"dark blue hair",
"bow hairband",
"cat hair ornament",
"musical note hair ornament",
"carrot hair ornament",
"purple hairband",
"hair tucking",
"hair beads",
"multiple hair bows",
"hairpods",
"bat hair ornament",
"bone hair ornament",
"orange hairband",
"multi",
"snowflake hair ornament",
];

@ -0,0 +1,76 @@
export const ORNAMENTS = [
"halo",
"mini_top_hat",
"beret",
"hood",
"nurse cap",
"tiara",
"oni horns",
"demon horns",
"hair ribbon",
"flower ribbon",
"hairband",
"hairclip",
"hair_ribbon",
"hair_flower",
"hair_ornament",
"bowtie",
"hair_bow",
"maid_headdress",
"bow",
"hair ornament",
"heart hair ornament",
"bandaid hair ornament",
"hair bun",
"cone hair bun",
"double bun",
"semi-rimless eyewear",
"sunglasses",
"goggles",
"eyepatch",
"black blindfold",
"headphones",
"veil",
"mouth mask",
"glasses",
"earrings",
"jewelry",
"bell",
"ribbon_choker",
"black choker",
"necklace",
"headphones around neck",
"collar",
"sailor_collar",
"neckerchief",
"necktie",
"cross necklace",
"pendant",
"jewelry",
"scarf",
"armband",
"armlet",
"arm strap",
"elbow gloves",
"half gloves",
"fingerless_gloves",
"gloves",
"fingerless gloves",
"chains",
"shackles",
"cuffs",
"handcuffs",
"bracelet",
"wristwatch",
"wristband",
"wrist_cuffs",
"holding book",
"holding sword",
"tennis racket",
"cane",
"backpack",
"school bag",
"satchel",
"smartphone",
"bandaid",
];

@ -62,13 +62,24 @@ export const GenerateScene = ({ setScene, prompts }: GenerateSceneProps) => {
<div> <div>
<img src={`data:image/jpeg;base64,${code}`}></img> <img src={`data:image/jpeg;base64,${code}`}></img>
<Divider /> <Divider />
6.7
<Divider />
<Button
variant={"outlined"}
onClick={() => {
setScene(GAME_SCENES.LOTTERY);
}}
>
</Button>
<Divider />
<Button <Button
variant={"outlined"} variant={"outlined"}
onClick={() => { onClick={() => {
setScene(GAME_SCENES.LOTTERY); setScene(GAME_SCENES.LOTTERY);
}} }}
> >
</Button> </Button>
</div> </div>
)} )}

@ -1,9 +1,11 @@
import { Button, CircularProgress, Divider } from "@mui/material"; import { Button, CircularProgress, Divider } from "@mui/material";
import { getLotteryPool } from "../keywords/dict"; import { getLotteryPool } from "../keywords/dict";
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useState } from "react";
import { GAME_SCENES, PromptToken, SceneProps } from "types"; import { GAME_SCENES, Keyword, SceneProps } from "types";
import { OpenAIService } from "service/gpt"; // import { OpenAIService } from "service/gpt";
import { Message } from "./ui"; import { Message } from "./ui";
import { randomSelectNoRepeat } from "utils/random";
import { getPrompts, initPrompts, mergePrompts } from "utils/prompt";
type LotterySceneProps = { type LotterySceneProps = {
setPrompts: React.Dispatch<React.SetStateAction<string[]>>; setPrompts: React.Dispatch<React.SetStateAction<string[]>>;
@ -11,7 +13,7 @@ type LotterySceneProps = {
type ActivePromptToken = { type ActivePromptToken = {
active: boolean; active: boolean;
} & PromptToken; } & Keyword;
/** 抽奖界面 */ /** 抽奖界面 */
export const LotteryScene = ({ setScene, setPrompts }: LotterySceneProps) => { export const LotteryScene = ({ setScene, setPrompts }: LotterySceneProps) => {
@ -19,10 +21,17 @@ export const LotteryScene = ({ setScene, setPrompts }: LotterySceneProps) => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const LOTTERY_POOL = getLotteryPool(); const LOTTERY_POOL = getLotteryPool();
const getPromptsByTokens = useCallback(async () => { const getPromptsByTokens = useCallback(async () => {
const { getPrompts } = await OpenAIService(); // const { getPrompts } = await OpenAIService();
const prompts = await getPrompts( // const prompts = await getPrompts(
activeTokens.filter((token) => token.active).map((token) => token.value) // activeTokens.filter((token) => token.active).map((token) => token.value)
); // );
let figurePrompts = initPrompts();
activeTokens
.filter((token) => token.active)
.forEach((token) => {
figurePrompts = mergePrompts(figurePrompts, token.prompts);
});
const prompts = getPrompts(figurePrompts);
console.log(prompts); console.log(prompts);
if (prompts) setPrompts(prompts); if (prompts) setPrompts(prompts);
}, [setPrompts, activeTokens]); }, [setPrompts, activeTokens]);
@ -31,21 +40,14 @@ export const LotteryScene = ({ setScene, setPrompts }: LotterySceneProps) => {
<Button <Button
variant="outlined" variant="outlined"
onClick={() => { onClick={() => {
const tokenLength = LOTTERY_POOL.length; setActiveTokens(
let availableTokenNum = 0; randomSelectNoRepeat(LOTTERY_POOL, 10, (obj) => {
let lottery = {} as any; return {
while (availableTokenNum < 10) { ...obj,
let code = Math.random() * tokenLength;
if (code === tokenLength) code -= 1;
code = Math.floor(code);
if (lottery[code]) continue;
lottery[code] = {
...LOTTERY_POOL[code],
active: false, active: false,
}; };
availableTokenNum++; })
} );
setActiveTokens(Object.values(lottery));
}} }}
> >

@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { GAME_SCENES, PromptToken } from "types"; import { GAME_SCENES, Keyword } from "types";
import { MenuScene } from "./menu"; import { MenuScene } from "./menu";
import { LotteryScene } from "./lottery"; import { LotteryScene } from "./lottery";
import { GenerateScene } from "./generate"; import { GenerateScene } from "./generate";

@ -1,10 +1,14 @@
import { Configuration, OpenAIApi } from "openai"; import { Configuration, OpenAIApi } from "openai";
export const OpenAIService = async () => { const params = {
const config = new Configuration({
organization: "org-ew4m4pHcq5yYaTGF4VtbSMGH", organization: "org-ew4m4pHcq5yYaTGF4VtbSMGH",
apiKey: "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", apiKey: "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",
}); // organization: "YOUR OWN ORGANIZATION HERE",
// apiKey: "YOUR OWN APIKEY HERE",
};
export const OpenAIService = async () => {
const config = new Configuration(params);
const openai = new OpenAIApi(config); const openai = new OpenAIApi(config);
return { return {
openai, openai,

@ -23,7 +23,35 @@ export type SceneProps = {
setScene: React.Dispatch<React.SetStateAction<GAME_SCENES>>; setScene: React.Dispatch<React.SetStateAction<GAME_SCENES>>;
}; };
export type PromptToken = { export type FigurePrompts = {
base?: string[];
style?: string[];
character?: string;
role?: string[];
action?: string;
environmentTime?: string;
environmentSky?: string;
environmentLocation?: string;
hairLength?: string;
hairColor?: string;
hairStyle?: string;
hairBraid?: string;
hairBangs?: string;
hairOrnament?: string;
eyeColor?: string;
eyeStyle?: string;
eyeStatus?: string;
facialFeature?: string;
facialExpression?: string;
bodyBreasts?: string;
bodyClothing?: string;
bodyLegOrnaments?: string;
bodyShoes?: string;
ornaments?: string[];
};
export type Keyword = {
value: string; value: string;
class: "n" | "v" | "adj" | "adv"; class: "n" | "v" | "adj" | "adv";
prompts: FigurePrompts;
}; };

@ -0,0 +1,118 @@
import { FigurePrompts } from "types";
import { randomSelect, randomSelectNoRepeat } from "./random";
import { CHARACTER, ROLE } from "prompts/general";
import {
ENVIRONMENT_LOCATION,
ENVIRONMENT_SKY,
ENVIRONMENT_TIME,
} from "prompts/environment";
import {
HAIR_BANGS,
HAIR_BRAID,
HAIR_COLOR,
HAIR_LENGTH,
HAIR_ORNAMENT,
HAIR_STYLE,
} from "prompts/hair";
import { EYE_COLOR, EYE_STATUS, EYE_STYLE } from "prompts/eye";
import { FACIAL_EXPRESSION, FACIAL_FEATURE } from "prompts/facial";
import {
BODY_BREASTS,
BODY_CLOTHING,
BODY_LEG_ORNAMENTS,
BODY_SHOES,
} from "prompts/body";
import { ORNAMENTS } from "prompts/ornament";
export const initPrompts = (p?: FigurePrompts): FigurePrompts => {
const _p: FigurePrompts = {
base: p?.base || [],
style: p?.style || [],
character: p?.character || randomSelect(CHARACTER),
role: p?.role || randomSelectNoRepeat(ROLE, 1),
action: p?.action,
environmentTime: p?.environmentTime || randomSelect(ENVIRONMENT_TIME),
environmentSky: p?.environmentSky || randomSelect(ENVIRONMENT_SKY),
environmentLocation:
p?.environmentLocation || randomSelect(ENVIRONMENT_LOCATION),
hairLength: p?.hairLength || randomSelect(HAIR_LENGTH),
hairColor: p?.hairColor || randomSelect(HAIR_COLOR),
hairStyle: p?.hairStyle || randomSelect(HAIR_STYLE, 0.5),
hairBraid: p?.hairBraid || randomSelect(HAIR_BRAID, 0.8),
hairBangs: p?.hairBangs || randomSelect(HAIR_BANGS, 0.8),
hairOrnament: p?.hairOrnament || randomSelect(HAIR_ORNAMENT, 0.8),
eyeColor: p?.eyeColor || randomSelect(EYE_COLOR, 0.5),
eyeStyle: p?.eyeStyle || randomSelect(EYE_STYLE, 0.5),
eyeStatus: p?.eyeStatus || randomSelect(EYE_STATUS, 0.8),
facialFeature: p?.facialFeature || randomSelect(FACIAL_FEATURE, 0.8),
facialExpression:
p?.facialExpression || randomSelect(FACIAL_EXPRESSION, 0.8),
bodyBreasts: p?.bodyBreasts || randomSelect(BODY_BREASTS, 0.5),
bodyClothing: p?.bodyClothing || randomSelect(BODY_CLOTHING, 0.5),
bodyLegOrnaments:
p?.bodyLegOrnaments || randomSelect(BODY_LEG_ORNAMENTS, 0.5),
bodyShoes: p?.bodyShoes || randomSelect(BODY_SHOES, 0.5),
ornaments: p?.ornaments || randomSelectNoRepeat(ORNAMENTS, 2),
};
return _p;
};
export const mergeArray = (
arr1: any[] | undefined,
arr2: any[] | undefined
) => {
const arr = [] as any[];
if (Array.isArray(arr1)) {
arr.push(...arr1);
} else if (arr1) {
arr.push(arr1);
}
if (Array.isArray(arr2)) {
arr.push(...arr2);
} else if (arr2) {
arr.push(arr2);
}
return arr;
};
export const mergePrompts = (
p1: FigurePrompts,
p2: FigurePrompts
): FigurePrompts => {
const _p: FigurePrompts = {
base: mergeArray(p1.base, p2.base),
style: mergeArray(p1.style, p2.style),
character: p2.character || p1.character,
role: mergeArray(p1.role, p2.role),
action: p2.action || p1.action,
environmentTime: p2.environmentTime || p1.environmentTime,
environmentSky: p2.environmentSky || p1.environmentSky,
environmentLocation: p2.environmentLocation || p1.environmentLocation,
hairLength: p2.hairLength || p1.hairLength,
hairColor: p2.hairColor || p1.hairColor,
hairStyle: p2.hairStyle || p1.hairStyle,
hairBraid: p2.hairBraid || p1.hairBraid,
hairBangs: p2.hairBangs || p1.hairBangs,
hairOrnament: p2.hairOrnament || p1.hairOrnament,
eyeColor: p2.hairColor || p1.hairColor,
eyeStyle: p2.eyeStyle || p1.eyeStyle,
eyeStatus: p2.eyeStatus || p1.eyeStyle,
facialFeature: p2.facialFeature || p1.facialFeature,
facialExpression: p2.facialExpression || p1.facialExpression,
bodyBreasts: p2.bodyBreasts || p1.bodyBreasts,
bodyClothing: p2.bodyClothing || p1.bodyClothing,
bodyLegOrnaments: p2.bodyLegOrnaments || p1.bodyLegOrnaments,
bodyShoes: p2.bodyShoes || p1.bodyShoes,
ornaments: mergeArray(p1.ornaments, p2.ornaments),
};
return _p;
};
export const getPrompts = (p: FigurePrompts): string[] => {
const prompts = [] as string[];
Object.values(p).forEach((value) => {
if (typeof value === "string") prompts.push(value);
else if (Array.isArray(value)) prompts.push(...value);
});
return prompts;
};

@ -0,0 +1,32 @@
export const randomSelectNoRepeat = (
arr: string[] | any[],
count: number,
mapper?: (obj: any) => any
) => {
const length = arr.length;
let availableNum = 0;
let lottery = {} as any;
while (availableNum < count) {
let code = Math.random() * length;
if (code === length) code -= 1;
code = Math.floor(code);
if (lottery[code]) continue;
lottery[code] = mapper
? mapper(arr[code])
: typeof arr[code] === "string"
? arr[code]
: {
...arr[code],
};
availableNum++;
}
return Object.values(lottery) as any[];
};
export const randomSelect = (arr: any[], noReturn = 0) => {
if (Math.random() < noReturn) return undefined;
const length = arr.length;
let code = Math.random() * length;
if (code === length) code -= 1;
return arr[code];
};
Loading…
Cancel
Save