Initial file uploads

This commit is contained in:
7trail 2023-08-28 18:53:17 -05:00 committed by GitHub
parent 72230fe676
commit b611a6bbbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 844 additions and 0 deletions

26
generate.py Normal file
View file

@ -0,0 +1,26 @@
from poe_api_wrapper import PoeApi
import os
client = PoeApi(os.environ['pb'])
import asyncio
#from revChatGPT.V1 import AsyncChatbot
#chatbot = AsyncChatbot(config={
# "email": os.environ['email'],
# "password": os.environ['pass']
#})
#Auth
async def GetText(prompt,bot = "chinchilla"):
prev_text = ""
#code = ""
for chunk in client.send_message(bot, prompt, suggest_replies=True):
await asyncio.sleep(0.05)
prev_text = chunk["text"]
client.delete_chat(bot, del_all=True)
#client.chat_break(bot, chatCode = code)
#async for data in chatbot.ask(prompt):
# message = data["message"][len(prev_text) :]
# #print(message, end="", flush=True)
# prev_text = data["message"]
return prev_text

509
itemname.py Normal file
View file

@ -0,0 +1,509 @@
import random
bases = """sword
axe
hammer
amulet
potion
broom
orb
cloak
armor
circlet
boots
bag
shield
shackles
glasses
helmet
book
bow
ring
socks
ointment
deck
fork
cart
boat
paper
arrows
apparatus
slippers
greaves
staff
skull
head
hand
glue
quiver
token
instrument
mirror
flask
keg
javelin
dagger
maul
shuriken
spiked chain
dust
gem
gate
carpet
candle
crystal ball
fortress
figurine
hat
portable ram
trap
box
ioun stone
horn
trinket
machine"""
locations = """
fantasy village
magic forest
dragon's lair
enchanted castle
elven city
dwarven mine
wizard's tower
haunted graveyard
orc stronghold
goblin cave
dark swamp
knight's training ground
sorcerer's academy
thieves' guild hideout
mermaid's cove
troll bridge
fairy glen
undead crypt
wizard's library
druidic grove
witch's hut
treasure-filled dungeon
mystical ruins
celestial observatory
elemental plane
astral realm
planar crossroads
forgotten temple
abyssal rift
angelic citadel
shadowy underworld
lycanthrope den
necromancer's sanctum
clockwork workshop
warlock's pact realm
underground city
beastman encampment
mysterious island
underwater cavern
timeless pocket dimension
arcane battleground
demon-infested wasteland
divine garden
floating fortress
jungle temple
mad alchemist's laboratory
phoenix nest
twisted labyrinth
ghost ship
oracle's sanctuary
giant's stronghold
golem foundry
dreamwalker's realm
vampire's castle
plague-ridden village
wandering nomad camp
entangled thicket
celestial court
abandoned celestial city
forgotten astral prison"""
creatures = """
dragon
goblin
orc
elf
dwarf
troll
gnome
kobold
centaur
minotaur
harpy
siren
merfolk
sphinx
unicorn
phoenix
werewolf
vampire
zombie
skeleton
ghost
demon
angel
fairy
giant
ogre
cyclops
hydra
chimera
griffin
wyvern
elemental
golem
gargoyle
lich
beholder
mind flayer
nymph
satyr
kraken
manticore
djinn
mummy
wraith
gorgon
kraken
pegasus
treant
lamia
basilisk
rakshasa
salamander
changeling
hobgoblin
tengu
mimic
rust monster
blink dog
displacer beast"""
spells = """
enchantment
evocation
illusion
conjuration
abjuration
transmutation
necromancy
divination
charm
hex
curse
blessing
summoning
compulsion
protection
fire
ice
lightning
earth
wind
water
shadow
light
healing
banishment
augmentation
teleportation
mind control
time manipulation
creation
destruction
hexbreaking
illusion
shape-shifting
warding
fortune-telling
invisibility
mind reading
telekinesis
fear
love
truth
memory manipulation
elemental manipulation
fate weaving
spiritual communion
phasing
soulbinding
telepathy
dreamwalking
alchemy
curses
blessings
illusion
prophecy
necromancy
weather manipulation
energy drain
astral projection
illusion
healing
enhancement
demonology
angelic intervention
teleportation
creation
hexbreaking
warding
fey magic
geomancy
songweaving
runecasting
starcalling
chronomancy
geomancy
psionics
planar manipulation
mind melding
polymorphing
molecular disruption
pyromancy
aquamancy
aeromancy
terramancy
cryomancy
celestial magic
transfiguration
curse-breaking
illusion
portal manipulation
spirit calling
divine intervention
time dilation
cosmic manipulation
cataclysmic spells
reanimation
perception alteration
dimensional manipulation
soul manipulation"""
enchantments = """flaming
frost
healing
adamantine
death
commanding elementals
flying
talking
awakened
teleportation
unlocking
lucky
unlucky
instant
illusion
illusionary
many things
dwarven
draconic
disguise
feindish
knowledge
toughness
serpentine
folding
theives
holding
devouring
alien
eldritch
fireball
archmage
cubic
crab
stars
wild
natural
lycanthrope (wolf)
ursanthrope (bear)
felinethrope (tiger)
smashing
horripilating
revivification
holy
unholy
gravity
paper
mechanical
electricity
sonic
endless water
cursed (make something up)
jousting
charming
swarming
swarming insects
snake
fuzzy
soft
lifestealing
vorpal
the sphere
ultimate evil
pure good
true neutral
tentacle
enemy detection
secret
wonder
vecna
fish command
sticky
creative
rulership
eyes
fire resistance
telekinesis
wishes
x-ray vision
animal influence
limitless
wild magic
the sewers
todd
love
life trapping
soul trapping
tripping
psychadelic
berserker
dry
elvenkind
displacement
winterlands
northern
levitating
arrow attraction
bat
manta ray
arachnida
drow
glamerous
free action
jumping
warmth
regeneration
annihilation
refridgeration
spherical
monkey
primal
psychic
woodlands
sharpness
smiting
bane of arthropods
fear
web
plane shift
winged
sun
son
spellguard
gaseous form
gaseous
valhalla
horned
golden lion
purple
enlargement
shrinking
slaying
tricky
awakened
unsheathed
prime
mystical
gleaming
enchanted
cursed
ancient
radiant
shadowy
whispering
ornate
runed
ethereal
intricate
glowing
forgotten
dreadful
celestial
fiery
frozen
arcane
serrated
ebon
gilded
luminous
sacrificial
arcane
malevolent
resplendent
vorpal
vengeful
vibrant
timeless
abyssal
otherworldly
necrotic
transcendent
perfected
empyreal
crimson
iridescent
eldritch
corrupted
thunderous
prismatic
harmonious
molten
umbral
blighted
harbinger
fey
pristine
titanic
ethereal
phantom
penumbral
verdant
infernal"""
#basesList = bases.split("\n")
#print(basesList)
enchantmentsList = enchantments.split("\n")
#print(enchantmentsList)
magicItemList = []
def makeItem(baseString = bases):
base = getBase(baseString.split("\n"))
enchantment = getEnchantment()
magicItem = ""
roll = random.randint(0,20) #rolls to see if it's
if roll < 10: #[ENCHANTMENT] [BASE] (10/21)
magicItem += enchantment+" "+base
elif roll == 20:#[ENCHANTMENT] [BASE] of [ENCHANTMENT 2] (1/21)
enchantment2 = getEnchantment()
magicItem += enchantment+" "+base+" of "+enchantment2
else: #or [BASE] of [ENCHANTMENT] (10/21)
magicItem += base+" of "+enchantment
return magicItem
def getEnchantment():
return enchantmentsList[random.randint(0,len(enchantmentsList)-1)]
def getBase(ls):
return ls[random.randint(0,len(ls)-1)]

21
keep_alive.py Normal file
View file

@ -0,0 +1,21 @@
from flask import Flask
from threading import Thread
app = Flask('')
header = "None"
body = "The next thing generated will show here!"
@app.route('/')
def home():
return f"""<h1>Latest - {header}</h1>
{body}
"""
def run():
app.run(host='0.0.0.0',port=8080)
def keep_alive():
t = Thread(target=run)
t.start()

22
license.txt Normal file
View file

@ -0,0 +1,22 @@
For the contents of itemname.py
MIT License
Copyright (c) 2019 Michaelofthepi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

180
main.py Normal file
View file

@ -0,0 +1,180 @@
import os
import discord
import generate
import neural
import itemname
import random
import re
from discord import app_commands
from discord.ext import tasks
import keep_alive
from keep_alive import keep_alive
client = discord.Client(intents=discord.Intents.all())
tree = app_commands.CommandTree(client)
queue = []
guildID = 1081397933276155977
magicForum = 1144040531240964256
raceForum = 1144075835217825868
subclassForum = 1144075898870579290
locationForum = 1144075950749925457
monsterForum = 1144081512724176947
npcForum = 1144425240018034878
otherForum = 1144426051720724602
botID = 1144041248303366314
logChannel = 1144064721922834582
@client.event
async def on_message(message):
if message.author != client.user:
pass
@client.event
async def on_thread_create(thread):
# await thread.send("## Sample Concept Art Being Generated")
await neural.Generate(f"art of the '{thread.name}', a form of {thread.parent.name}",thread)
@tree.command(name = "magicitem", description = "Generate a new magic item!", guild=discord.Object(id=guildID))
async def magicitem(interaction, name:str, desc: str = ""):
queue.append(["magic item", name,desc + ", and Give detailed rules for item effects and flavor accordingly. Keep non-artifact, non-legendary magic items simple.", magicForum, interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "race", description = "Generate a new race!", guild=discord.Object(id=guildID))
async def race(interaction, name:str, desc: str = ""):
queue.append(["race", name,desc, , interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "subclass", description = "Generate a new subclass!", guild=discord.Object(id=guildID))
async def subclass(interaction, name:str, desc: str = ""):
queue.append(["subclass", name,desc, , interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "location", description = "Generate a new location!", guild=discord.Object(id=guildID))
async def location(interaction, name:str, desc: str = ""):
queue.append(["location", name,desc+", and Describe the location in detail. Provide key locations and any necessary information on NPCs.", locationForum, interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "monster", description = "Generate a new monster!", guild=discord.Object(id=guildID))
async def monster(interaction, name:str, desc: str = ""):
queue.append(["living being", name,desc + ", and Give adequate description to both the flavoring of the monster AND the stat block.", monsterForum, interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "npc", description = "Generate a new npc!", guild=discord.Object(id=guildID))
async def npc(interaction, name:str, desc: str = ""):
queue.append(["NPC", name,desc + ". Provide a stat block for the NPC, but also include a bond, ideal, personality trait, and flaw. Offer a potential quest involving the NPC.", , interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "other", description = "Generate a new npc!", guild=discord.Object(id=guildID))
async def other(interaction, name:str, type:str = "spell", desc: str = ""):
queue.append([type, name,f"Be sure to follow all rules surrounding the {type}.", 1144426051720724602, interaction.user.id])
embedVar = discord.Embed(title=f'Queue position: {len(queue)}', description=f"It won't be long until we get around to the '{name}'!", color=0xffff00)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "ask", description = "Use in a thread to get more details!", guild=discord.Object(id=guildID))
async def ask(interaction, question:str):
if interaction.channel.type == discord.ChannelType.public_thread or interaction.channel.type == discord.ChannelType.forum:
embedVar = discord.Embed(title=f'Reply inbound', description=f"Question: {question}", color=0xffffff)
await interaction.response.send_message(embed=embedVar)
#The important code
ctx = ""
async for message in interaction.channel.history(limit=100,oldest_first=True):
if str(message.author.id) == str(botID):
ctx += message.content
await interaction.channel.send(await generate.GetText(f"You are being asked a question about a piece of DND 5E content. The piece of content is: \n{ctx} \n\nThe question is: {question}. Answer the question thoroughly, but keep it less than 200 words. You do not need to restate any of the content's material nor that this is for DND 5E."))
else :
embedVar = discord.Embed(title=f'Invalid location', description=f"Do this inside of a forum post for context-specific results!", color=0xff0000)
await interaction.response.send_message(embed=embedVar)
@tree.command(name = "conceptart", description = "Generate concept art!", guild=discord.Object(id=guildID))
async def conceptart(interaction, prompt:str):
embedVar = discord.Embed(title=f'Art inbound!', description=f"Prompt: '{prompt}'", color=0xffffff)
await interaction.response.send_message(embed=embedVar)
await neural.Generate(f"{prompt}", interaction.channel)
intervals = 0
alreadyGenerating = False
async def AddAutoGen(amount):
if amount > 10:
return
for i in range(amount):
v = random.choice([0,1,2,3 ])
if v == 0:
queue.append(["magic item", itemname.makeItem().title(),"Give detailed rules for item effects and mechanics.", magicForum, -1])
elif v == 1:
queue.append(["living being", itemname.makeItem(itemname.creatures).title(),"Give adequate description to both the flavoring of the monster AND the stat block.", monsterForum, -1])
elif v == 2:
queue.append(["location", itemname.makeItem(itemname.locations).title(),"Describe the location in detail. Provide key locations and any necessary information on NPCs.", locationForum, -1])
elif v == 3:
queue.append(["spell", itemname.makeItem(itemname.spells).title(),"Be sure to follow all rules surrounding the spell.", otherForum, -1])
@tasks.loop(minutes=0.25)
async def FlushQueue():
global alreadyGenerating
global intervals
try:
if alreadyGenerating:
return
alreadyGenerating = True
if len(queue) == 0:
intervals = (intervals+1)%10
if intervals == 0:
await AddAutoGen(1)
if len(queue) > 0:
obj = queue.pop(0)
keep_alive.header = obj[1]
obj[1] = re.sub('[^A-Za-z0-9 ]+', '', obj[1])
log = client.get_channel(logChannel)
await log.send(f"**Now generating the {obj[0]} '{obj[1]}'**")
channel = client.get_channel(obj[3])
st = f"Create a DND 5e {obj[0]} named the '{obj[1]}'. {obj[2]} Keep the final text under 300 words. Use markdown text formatting."
c = await generate.GetText(st)
keep_alive.body = c
if len(c) > 1900:
c2 = c[1899:(len(c)-1)]
c = c[0:1899]
thread = await channel.create_thread(name = obj[1], content = c + " (Truncated)")
await thread.thread.send(c2)
if (obj[4]!=-1):
await thread.thread.send("<@" + str(obj[4]) + ">")
else:
await thread.thread.send("Autogenerated by the bot")
else:
thread = await channel.create_thread(name = obj[1], content = c)
if (obj[4]!=-1):
await thread.thread.send("<@" + str(obj[4]) + ">")
else:
await thread.thread.send("Autogenerated by the bot")
alreadyGenerating = False
except Exception as e:
log = client.get_channel(logChannel)
await log.send("I'm just as confused as you are, there was an error somehow! The next time it should work though.")
await log.send("Error message: " + str(e))
alreadyGenerating = False
@client.event
async def on_ready():
print("I'm in")
print(client.user)
await tree.sync(guild=discord.Object(id=guildID))
log = client.get_channel(logChannel)
await log.send("Bot now online")
FlushQueue.start()
keep_alive()
my_secret = os.environ['discordbot']
client.run(my_secret)

86
neural.py Normal file
View file

@ -0,0 +1,86 @@
import asyncio
import os
import requests
from io import BytesIO
from PIL import Image
import discord
def create_image(links):
images=[]
for index in links:
response = requests.get(index)
images.append(Image.open(BytesIO(response.content)))
image = Image.new("RGB", (images[0].width*len(images), images[0].height))
i=0
for img in images:
image.paste(images[i], (images[i].width*i, 0))
i+=1
return image
async def Generate(prompt, channel, count=2, negativePrompt = "",size="square"):
url = "https://api.neural.love/v1/ai-art/generate"
payload = {
"amount": count,
"isPublic": True,
"isPriority": False,
"isHd": False,
"steps": 25,
"cfgScale": 7.5,
"prompt": prompt,
"style": "anything",
"layout": size,
"negativePrompt": negativePrompt
}
headers = {
"accept":
"application/json",
"content-type":
"application/json",
"authorization":
os.environ['neural']
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
if not "orderId" in data.keys():
await channel.send("**Error while generating, try again?**")
return
orderId = data["orderId"]
print(orderId)
url2 = "https://api.neural.love/v1/ai-art/orders/" + orderId
print(url2)
headers2 = {
"accept":
"application/json",
"authorization":
os.environ['neural']
}
count = 0
while True:
await asyncio.sleep(3)
response2 = requests.get(url2, headers=headers2)
count += 1
data2 = response2.json()
if data2["status"]["isReady"]:
links = []
for i in range(data2["input"]["amount"]):
data3 = data2["output"][i]
links.append(data3["full"])
with BytesIO() as image_binary:
create_image(links).save(image_binary, 'PNG')
image_binary.seek(0)
await channel.send(file=discord.File(fp=image_binary, filename='image.png'))
break
elif data2["status"]["code"] == 998:
await channel.send("All results were NSFW, aborting!")
break
elif count > 10:
await channel.send("Taking too long, aborting!")
break
else:
#await message.channel.send("Not done, waiting 10 seconds to retry..."
await asyncio.sleep(7)