hashhub/main.py

1354 lines
43 KiB
Python

import sys
# Justus Jan Nico Wolff
sys.dont_write_bytecode = True
stderrfile = open("errors.log", 'w', buffering=1)
sys.stderr = stderrfile
import subprocess
import pkg_resources
import ast
def installmodules(required, silent=False):
required = required
installed = {pkg.key for pkg in pkg_resources.working_set}
missing = required - installed
if missing:
if silent == False:
while True:
ans = input(f"Einige benötigte Module sind nicht installiert ({missing}), installieren per pip? Y/N ")
if ans == "y":
python = sys.executable
subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
break
elif ans == "n":
exit()
else:
python = sys.executable
subprocess.check_call([python, '-m', 'pip', 'install', *missing], stdout=subprocess.DEVNULL)
installmodules(ast.literal_eval(open("requirements.txt", 'r').read()))
import mtTkinter as tk
from tkinter import ttk as tkk
from tkinter import messagebox
from tkinter import filedialog
import copy
from PIL import Image
import hashengine
def norms():
global LH
import PCPL
import langsys
PCPL.interpreter.ENG = hashengine
LH = langsys.langhandler()
lang = open("clang", 'r')
lang = lang.read()
LH.setlang(lang)
# LH.string("")
def replacelh():
global LH
class rLH:
def __init__(self):
pass
def string(self, target):
return target
def getlangs(self):
return ()
LH = rLH()
if __name__ == "__main__":
norms()
else:
replacelh()
if len(sys.argv) == 2:
if sys.argv[1] == "NOLANG":
replacelh()
import time
import shutil
import os
import random
import string
import easygui
import base64
import simpleaudio as sa
import multiprocessing
import threading
global gamedata
global cooldown
global version
global plugindir
version = "HE2.2-Hashengine V2.2"
plugindir = "plugins"
#plugindir = "testplugins"
cooldown = False
gamedata = {}
def prepspecified(target):
out = []
tempwin = tk.Tk()
bar = tkk.Progressbar(tempwin)
bar.place(width=200)
ptext = tk.Label(tempwin, text="NONE")
ptext.place()
count = 1
modellist = {}
for i in target:
id = i
i = gamedata[i]
ptext.config(text=i["name"])
bar.step(count/len(gamedata))
count += 1
tempwin.update()
temp = {"id": i["id"], "name": i["name"], "SID": i["SID"],}
tempargs = {}
tosearch = {}
for arg in i["args"]:
if not arg in extypes and not arg in ignoreat and arg != "sdata":
tosearch[arg] = i["args"][arg]
continue
if arg in ignoreat and arg != "sdata": continue
if arg != "sdata":
tempargs[arg] = i["args"][arg]
else:
tempargs[arg] = str(base64.b64encode(i["args"][arg]), "ascii", "ignore")
#tempargs[arg] = i["args"][arg]
for argname in tosearch:
arg = tosearch[argname]
temp2 = getattributes(arg)
temp2.update({"ARGID": arg._type})
tempargs[argname] = temp2
if objtree.parent(id) != "":
modelname = objtree.item(objtree.parent(id), "text")
if not modelname in list(modellist.keys()):
modellist[modelname] = []
modellist[modelname].append(count-2)
temp["args"] = tempargs
out.append(temp)
tempwin.destroy()
return [out, modellist, gamexsize, gameysize]
class script:
def __init__(self):
self.code = ""
def execute(self, API, log):
#old code for PCPL code execution, replaced with python code execution
"""
PCPL.resetvar()
PCPL.LIS("HASHBASE")
PCPL.run(self.code)"""
try:
exec(self.code, API)
except Exception as e:
log(f"[GAME] Exception occured in script: {e}")
class previewrend:
def __init__(self, size, cam, container, offset):
self._size = size
self._grid = {}
self._win = container
self._frame = tk.Frame(container)
self._posframe = tk.Frame(self._frame)
self._cam = cam
self._xcam = tk.Label(self._posframe, text="-")
self._ycam = tk.Label(self._posframe, text="-")
self._xcam.grid(row=size[1], column=0)
self._ycam.grid(row=size[1]+1, column=0)
tkeys = list(string.ascii_letters)
self._keys = {}
for i in tkeys:
self._keys[i] = False
self._win.bind("<KeyPress>", self.keypupd, add="+")
self._win.bind("<KeyRelease>", self.keydupd, add="+")
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(self._frame, text=" ", borderwidth=1, relief=tk.GROOVE, width=3)
temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update()
self._grid[f"{x}:{y}"] = temp
self._posframe.grid()
self._frame.grid()
def destroy(self):
self._posframe.destroy()
self._frame.destroy()
def keypupd(self, event):
event = event.char
if event in self._keys:
self._keys[event] = True
def keydupd(self, event):
event = event.char
if event in self._keys:
self._keys[event] = False
def getkeys(self):
return self._keys
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def select(self, x, y):
if f"{int(x)}:{int(y)}" in self._grid:
self._grid[f"{int(x)}:{int(y)}"].config(background="cyan")
self.update()
def deselect(self, x, y):
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(background="white")
self.update()
def pix(self, x, y, text, bcolor, fcolor):
self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x))
self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y))
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class render:
def __init__(self, size, cam, container, offset):
self._size = size
self._grid = {}
self._win = container
self._frame = tk.Frame(container)
self._posframe = tk.Frame(self._frame)
self._cam = cam
self._xcam = tk.Label(self._posframe, text="-")
self._ycam = tk.Label(self._posframe, text="-")
#self._xcam.grid(row=size[1], column=0)
#self._ycam.grid(row=size[1]+1, column=0)
tkeys = list(string.ascii_letters)
self._keys = {}
for i in tkeys:
self._keys[i] = False
self._win.bind("<KeyPress>", self.keypupd)
self._win.bind("<KeyRelease>", self.keydupd)
for y in range(size[1]):
for x in range(size[0]):
temp = tk.Label(self._frame, text=" ", width=3)
temp.grid(row=y+offset[1], column=x+offset[0]+1)
self._win.update()
self._grid[f"{x}:{y}"] = temp
self._posframe.grid()
self._frame.grid()
def keypupd(self, event):
event = event.char
if event in self._keys:
self._keys[event] = True
def keydupd(self, event):
event = event.char
if event in self._keys:
self._keys[event] = False
def getkeys(self):
return self._keys
def coltohex(self, target):
colors = []
target = [target.r, target.g, target.b]
for i in target:
colors.append(("0"*(2-len(hex(int(i))[2:])))+hex(i)[2:])
out = ""
for i in colors:
out = out + i
return "#"+out
def update(self):
self._win.update()
def pix(self, x, y, text, bcolor, fcolor):
self._xcam.config(text=LH.string("xcam")+str(self._cam.position.x))
self._ycam.config(text=LH.string("ycam")+str(self._cam.position.y))
if f"{x}:{y}" in self._grid:
self._grid[f"{x}:{y}"].config(text=text, bg=self.coltohex(bcolor), fg=self.coltohex(fcolor))
class nullrend:
def __init__(self, size, cam):
pass
def getkeys(self):
pass
def update(self):
pass
def pix(self, x, y, text, bcolor, fcolor):
pass
def selectlang(new):
lang = open("clang", 'w')
lang.write(new)
lang.close()
container.quit()
subprocess.Popen([sys.executable, __file__])
def add(objtype, parent="", render=True):
global objtree
obj = getattr(types, objtype)()
args = {}
for i in dir(obj):
if i.startswith("_"): continue
args[i] = getattr(obj, i)
temp = {"id": objtype, "args": args, "name": LH.string(objtype), "SID": genid()}
id = genid()
if GUIe == True: objtree.insert(parent, tk.END, text=LH.string(objtype), image=icons[objtype], iid=id, tags=("objsel"))
gamedata[id] = temp
if objtype in crucial:
preview.addobj(obj)
gamedata[id]["args"]["ID"] = obj.ID
if GUIe == True and render == True: preview.render()
return id
def renameobj():
target = objtree.focus()
if target == "": return
new = easygui.enterbox(LH.string("NN"), LH.string("rename"))
if new:
objtree.item(target, text=new)
if not "HASHMODEL" in objtree.item(target, "tags"):
gamedata[target]["name"] = new
def modelobjs():
#use detach and move
temp = objtree.selection()
targets = []
for i in temp:
if not "objsel" in objtree.item(i, "tags"): continue
if objtree.parent(i) != "": continue
if gamedata[i]["id"] == "obj":
targets.append(i)
tempid = genid()
objtree.insert("", tk.END, text=LH.string("IOM"), image=icons["model"], iid=tempid, tags=("HASHMODEL",))
for i in targets:
objtree.detach(i)
objtree.move(i, tempid, "end")
def demodelobjs():
#use detach and move
temp = objtree.focus()
if not "HASHMODEL" in objtree.item(temp, "tags"): return
for i in objtree.get_children(temp):
objtree.detach(i)
objtree.move(i, "", "end")
objtree.delete(temp)
def delobjg(target):
objtree.delete(target)
temp = gamedata.pop(target)
if temp["id"] in crucial:
preview.removeobjbyid(temp["args"]["ID"])
#preview.render()
def delobj():
target = objtree.selection()
if target == (): return
atritree.delete(*atritree.get_children())
for i in target:
if "HASHMODEL" in objtree.item(i, "tags"):
tempwin = tk.Tk()
stat = tk.Label(tempwin, text="NONE")
stat.grid()
speed = tk.Label(tempwin, text="NONE")
speed.grid()
tempwin.update()
count = 0
length = len(objtree.get_children(i))
fpscount = 0
timestamp = time.time()
fps = 0
for f in objtree.get_children(i):
delobjg(f)
stat.config(text=f"{count}/{length}")
speed.config(text=f"{fps}/s")
tempwin.update()
count += 1
fpscount += 1
if time.time()-timestamp > 0.1:
fps = fpscount*10
fpscount = 0
timestamp = time.time()
objtree.delete(i)
tempwin.destroy()
else:
delobjg(i)
preview.render()
def HMPC(event):
currentat = objtree.focus()
target = atritree.focus()
name = atritree.item(target, "text")
back = 0
if name == "x":
back = aposx(0)
elif name == "y":
back = aposy(0)
for i in objtree.get_children(currentat):
if not "ID" in gamedata[i]["args"]: continue
setattr(gamedata[i]["args"]["position"], name, getattr(gamedata[i]["args"]["position"], name)+back)
setattr(preview.getobjbyid(gamedata[i]["args"]["ID"]).position, name, getattr(preview.getobjbyid(gamedata[i]["args"]["ID"]).position, name)+back)
updselect(None)
def changemodelpos(event):
atritree.delete(*atritree.get_children())
atritree.insert("", index=tk.END, text="x", tags=("OA",))
atritree.insert("", index=tk.END, text="y", tags=("OA",))
atritree.insert("", index=tk.END, text="SEQSID", values=(calcseqsid(objtree.focus())), tags=("SID",))
def calcseqsid(target):
out = ""
for f in objtree.get_children(target):
out = out + gamedata[f]["SID"][:5]
return out
def rpopup(event):
try:
rmenu.tk_popup(event.x_root, event.y_root)
finally:
rmenu.grab_release()
def getattributes(target):
out = {}
for i in dir(target):
if i.startswith("_"): continue
out[i] = getattr(target, i)
return out
def copySID(event):
target = atritree.focus()
text = atritree.item(target, "values")[0]
container.clipboard_clear()
container.clipboard_append(text)
messagebox.showinfo(LH.string("done"), LH.string("copied"))
def updatribute(event):
global currentat
target = objtree.focus()
currentat = target
atritree.delete(*atritree.get_children())
for i in gamedata[target]["args"]:
if i in ignoreat: continue
if i in valtypes and not i in DCTE:
val = gamedata[target]["args"][i]
atritree.insert("", tk.END, text=i, values=(val), tags=("FA", ))
elif i in valtypes and i in DCTE:
atritree.insert("", tk.END, text=i, values=("<DCTE>"), tags=("FA", ))
else:
root = atritree.insert("", tk.END, text=i, tags=("FA", ))
temp = getattributes(gamedata[target]["args"][i])
for f in temp:
atritree.insert(root, tk.END, text=f, values=(temp[f]), tags=("FA", ))
atritree.insert("", tk.END, text="SID", values=(gamedata[target]["SID"]), tags=("SID", ))
def halatribute(event):
target = atritree.focus()
name = atritree.item(target, "text")
parent = atritree.parent(target)
currentobj = currentat
if name in valtypes:
if parent == "":
new = valtypes[name](gamedata[currentobj]["args"][name])
gamedata[currentobj]["args"][name] = new
if "ID" in gamedata[currentobj]["args"]:
temp = preview.getobjbyid(gamedata[currentobj]["args"]["ID"])
setattr(temp, name, new)
atritree.delete(*atritree.get_children())
objtree.focus("")
else:
parent = atritree.item(parent, "text")
new = valtypes[name](getattr(gamedata[currentobj]["args"][parent], name))
setattr(gamedata[currentobj]["args"][parent], name, new)
if "ID" in gamedata[currentobj]["args"]:
temp = preview.getobjbyid(gamedata[currentobj]["args"]["ID"])
setattr(getattr(temp, parent), name, new)
atritree.delete(*atritree.get_children())
objtree.focus("")
updselect(None)
preview.render()
def updatepreviewcam(char):
global cooldown
if cooldown == True: return
cooldown = True
char = char.char
allowed = ["w", "a", "s", "d"]
if not char in allowed: return
if char == "w": preview.camera.position += hashengine.vector2(y=1)
if char == "a": preview.camera.position += hashengine.vector2(x=1)
if char == "s": preview.camera.position -= hashengine.vector2(y=1)
if char == "d": preview.camera.position -= hashengine.vector2(x=1)
updselect(None)
time.sleep(.0)
cooldown = False
def save():
target = filedialog.asksaveasfile()
target.write(str(prepspecified(gamedata)))
target.close()
messagebox.showinfo(LH.string("suc"), LH.string("save-suc"))
def clear():
global gamedata
objtree.delete(*objtree.get_children())
atritree.delete(*atritree.get_children())
gamedata = {}
preview._objects = {}
preview.camera.position = hashengine.vector2()
preview.render()
def importsound(target):
oid = add("rawsound")
gamedata[oid]["name"] = target["name"]
gamedata[oid]["args"]["sdata"] = base64.b64decode(target["args"]["sdata"])
gamedata[oid]["args"]["spath"] = target["args"]["spath"]
if "SID" in target:
gamedata[oid]["SID"] = target["SID"]
if GUIe == True: objtree.item(oid, text=target["name"])
def importobj(target):
if target["id"] == "sound" or target["id"] == "rawsound":
importsound(target)
return
oid = add(target["id"])
id = gamedata[oid]
id["name"] = target["name"]
if "SID" in target:
id["SID"] = target["SID"]
if GUIe == True: objtree.item(oid, text=target["name"])
#create arguments
outargs = {}
for argname in target["args"]:
arg = target["args"][argname]
if isinstance(arg, dict):
ID = arg.pop("ARGID")
obj = attypes[ID]()
for i in arg:
setattr(obj, i, arg[i])
arg = obj
outargs[argname] = arg
#apply arguments to obj
if target["id"] in crucial:
for i in outargs:
setattr(preview.getobjbyid(gamedata[oid]["args"]["ID"]), i, outargs[i])
id["args"].update(outargs)
return oid
def load(cleargame=True, GUI=True, path="", override=False):
if GUI == True:
file = filedialog.askopenfile()
elif override == False:
file = open(path, 'r')
tempwin = tk.Tk()
ptext = tk.Label(tempwin, text="NONE")
ptext.place(y=30)
stat = tk.Label(tempwin, text="NONE")
stat.place(y=50)
if override == False:
target = file.read()
file.close()
else:
target = override
target = ast.literal_eval(target)
if cleargame:
global models
models = []
clear()
if len(target) == 0: return
if not isinstance(target[0], list):
#very old save file
count = 1
bar = tkk.Progressbar(tempwin, maximum=len(target))
bar.place(width=200)
for i in target:
ptext.config(text="Current: "+i["name"])
bar.step()
stat.config(text=f"Object {count}/{len(target)}")
tempwin.update()
importobj(i)
count += 1
tempwin.destroy()
preview.render()
elif len(target) < 3:
#old save file
count = 1
bar = tkk.Progressbar(tempwin, maximum=len(target))
bar.place(width=200)
ids = {}
for i in target[0]:
ptext.config(text="Current: "+i["name"])
bar.step()
stat.config(text=f"Object {count}/{len(target)}")
tempwin.update()
id = importobj(i)
if id:
ids[count-1] = id
count += 1
for i in target[1]:
tempid = genid()
if GUIe == True: objtree.insert("", tk.END, text=i, image=icons["model"], iid=tempid, tags=("HASHMODEL",))
temp = []
for f in target[1][i]:
if GUIe == True:
objtree.detach(ids[f])
objtree.move(ids[f], tempid, "end")
temp.append(ids[f])
models.append(temp)
tempwin.destroy()
preview.render()
else:
#new save file
global gamexsize
global gameysize
count = 1
bar = tkk.Progressbar(tempwin, maximum=len(target[0]))
bar.place(width=200)
ids = {}
for i in target[0]:
ptext.config(text="Current: "+i["name"])
bar.step()
stat.config(text=f"Object {count}/{len(target[0])}")
tempwin.update()
id = importobj(i)
if id:
ids[count-1] = id
count += 1
for i in target[1]:
tempid = genid()
if GUIe == True: objtree.insert("", tk.END, text=i, image=icons["model"], iid=tempid, tags=("HASHMODEL",))
temp = []
for f in target[1][i]:
if GUIe == True:
objtree.detach(ids[f])
objtree.move(ids[f], tempid, "end")
temp.append(ids[f])
models.append(temp)
tempwin.destroy()
gamexsize = target[2]
gameysize = target[3]
if GUIe == True: initpreview()
preview.render()
def export():
temp = objtree.selection()
if temp == (): return
target = []
for i in temp:
if "HASHMODEL" in objtree.item(i, "tags"):
target.extend(objtree.get_children(i))
else: target.append(i)
back = prepspecified(target)
targetpath = filedialog.asksaveasfile()
if not targetpath: return
targetpath.write(str(back))
targetpath.close()
messagebox.showinfo(LH.string("suc"), LH.string("save-suc"))
def log(text, end="\n", flush=False):
global logfile
global clog
if clog:
if not os.path.exists("logs"):
os.mkdir("logs")
file = open("logs/"+logfile+".txt", 'a')
file.write(str(text)+end)
file.close()
def NULL():
pass
class gsound:
def __init__(self, data, game):
self._playing = False
self._data = data
game.currentsounds.append(self)
def play(self):
if self._playing == True: self.stop()
self._sound = sa.play_buffer(self._data, 2, 2, 44100)
self._playing = True
def stop(self):
if self._playing == False: return
self._sound.stop()
self._playing = False
def wait(self):
if self._playing == False: return
self._sound.wait_done()
def testing():
global testproc
global running
global clog
global APIPLUG
global RUNPLUG
try:
if running == True: return
except:
pass
running = True
testproc = multiprocessing.Process(target=execgame, args=(prepspecified(gamedata), clog.get(), APIPLUG, RUNPLUG))
testproc.start()
def APIGEN():
global APIPLUG
global maingame
API = {"print": log, "HASHBASE": hashengine}
API["HASHGAME"] = maingame
API["SOUND"] = lambda data: gsound(data, maingame)
API["PATHFIND"] = hashengine.pathfinding(maingame._size, list(maingame._objects.values()), maingame)
for i in APIPLUG:
exec(i, globals())
temp = globals()["PLUGINAPIFUNC"]()
API.update(temp)
return API
def run():
global logfile
global maingame
global window
temp = time.gmtime(time.time())
logfile = ""
for i in temp:
logfile = logfile + "S" + str(i)
log("Log file start!")
log(f"date: year: {temp[0]} month: {temp[1]} day: {temp[2]} hour: {temp[3]} min.: {temp[4]}, sec.: {temp[5]}")
log(f"Version: {version}")
log("Preparing API...")
log("Done!")
window = tk.Tk()
window.protocol("WM_DELETE_WINDOW", NULL)
maingame = hashengine.game(renderer=lambda size, cam: render(size, cam, window, [0, 0]), sounddir="/", size=[gamexsize, gameysize])
log("main game initalised!")
log("copying sounds...")
for i in gamedata:
i = gamedata[i]
if i["id"] != "sound" and i["id"] != "rawsound": continue
maingame.sounds[i["args"]["spath"]] = i["args"]["sdata"]
#skip = []
for i in gamedata:
GID = i
i = gamedata[i]
if i["id"] != "obj": continue
objid = i["args"]["ID"]
maingame._SIDS[i["SID"]] = objid
"""if objtree.parent(GID) != "" and not objtree.parent(GID) in skip:
skip.append(objtree.parent(GID))
out = ""
out2 = []
for f in objtree.get_children(objtree.parent(GID)):
out = out + gamedata[f]["SID"][:5]
out2.append(f)
maingame._SEQSIDS[out] = out2"""
for i in models:
out = []
SEQSID = ""
for f in i:
SEQSID = SEQSID + gamedata[f]["SID"][:5]
out.append(gamedata[f]["args"]["ID"])
maingame._SEQSIDS[SEQSID] = out
maingame._objects = copy.deepcopy(preview._objects)
"""
objects = copy.deepcopy(preview._objects)
maingame._objects = objects"""
scripts = []
for i in gamedata:
i = gamedata[i]
if i["id"] != "script": continue
i = i["args"]["code"]
obj = script()
obj.code = i
scripts.append(obj)
log("objects transferred!")
#gamescript = """
#global HASHGAME
#import time
#while True:
# for i in HASHGAME._objects:
# i = HASHGAME._objects[i]
# HASHGAME.calcphysobj(i)
# HASHGAME.render()
#"""
#gameloopsc = script()
#gameloopsc.code = gamescript
#maingame.startscript(lambda: gameloopsc.execute(APIGEN(), log))
log("executing plugins")
for i in RUNPLUG:
exec(i, globals())
log("done")
log("game test started!!!")
log("---------------------")
for i in scripts:
maingame.startscript(lambda: i.execute(APIGEN(), log))
#window.mainloop()
while True:
for i in maingame._objects:
i = maingame._objects[i]
maingame.calcphysobj(i)
maingame.render()
window.update()
def muladd(target):
for i in range(10):
add(target)
def stoptest():
global testproc
global running
try:
if running == False: return
except:
return
testproc.terminate()
running = False
def build():
print("asking user for output directory...")
target = filedialog.askdirectory()
os.mkdir(target+"/out")
target = target+"/out"
print("building started")
print("generating HEGF file...")
hegf = str(prepspecified(gamedata))
file = open(target+"/game.HEGF", 'w')
file.write(hegf)
file.close()
print("done.")
print("copying files...")
tocopy = ["mtTkinter.py", "hashengine.py"]
for i in tocopy:
print(f"copying {i}...")
shutil.copyfile(i, target+"/"+i)
shutil.copyfile(__file__, target+"/"+"player.py")
shutil.copyfile("requirements.txt", target+"/"+"requirements.txt")
shutil.copytree(plugindir, target+"/"+plugindir)
file = open(target+"/main.py", 'w')
file.write("""
import player
import ast
file = open("game.HEGF", 'r')
file = file.read()
file = ast.literal_eval(file)
temp = fAPIPLUG=player.loadplugins(False)
player.execgame(file, fAPIPLUG=temp[0], fRUNPLUG=temp[1])
""")
print("done.")
print("building finished!")
messagebox.showinfo(LH.string("done"), LH.string("suc"))
def importPS():
target = filedialog.askopenfile()
if target:
temp = add("script")
gamedata[temp]["args"]["code"] = str(target.read())
target.close()
def genid():
id = ""
chars = list(string.ascii_letters)
for i in range(255):
id = id + random.choice(chars)
return id
def COBS(target: str, offset=hashengine.vector2(), ignore=[" ",]):
origin = target
target = target.split("\n")
tempid = genid()
tempwin = tk.Tk()
stat = tk.Label(tempwin, text="NONE")
stat.grid()
speed = tk.Label(tempwin, text="NONE")
speed.grid()
tempwin.update()
if GUIe == True: objtree.insert("", tk.END, text=LH.string("IOM"), image=icons["model"], iid=tempid, tags=("HASHMODEL",))
count = 1
fpscount = 0
timestamp = time.time()
fps = 0
for i in range(len(target)):
y = i
i = target[i]
for f in range(len(i)):
x = f
f = i[x]
stat.config(text=f"{count}/{len(origin)}")
speed.config(text=f"{fps}/s")
tempwin.update()
count += 1
fpscount += 1
if time.time()-timestamp > 0.1:
fps = fpscount*10
fpscount = 0
timestamp = time.time()
if f in ignore:
continue
temp = add("obj", tempid, False)
objtree.item(temp, text=f)
#gamedata[temp]["args"]["ID"]
gamedata[temp]["args"]["char"] = f
gamedata[temp]["name"] = f
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "char", f)
gamedata[temp]["args"]["position"] = hashengine.vector2(x, y)+offset
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "position", hashengine.vector2(x, y)+offset)
gamedata[temp]["args"]["anchored"] = True
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "anchored", True)
gamedata[temp]["args"]["collide"] = True
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "collide", True)
#preview.render()
updselect(None)
tempwin.destroy()
def COBI(target, offset=hashengine.vector2()):
target = Image.open(target)
target = target.resize(preview._size)
tempid = genid()
tempwin = tk.Tk()
stat = tk.Label(tempwin, text="NONE")
stat.grid()
speed = tk.Label(tempwin, text="NONE")
speed.grid()
tempwin.update()
if GUIe == True: objtree.insert("", tk.END, text=LH.string("IOM"), image=icons["model"], iid=tempid, tags=("HASHMODEL",))
count = 1
fpscount = 0
timestamp = time.time()
fps = 0
for y in range(preview._size[1]):
y
for x in range(preview._size[0]):
stat.config(text=f"{count}/{preview._size[0]*preview._size[1]}")
speed.config(text=f"{fps}/s")
tempwin.update()
count += 1
fpscount += 1
if time.time()-timestamp > 0.1:
fps = fpscount*10
fpscount = 0
timestamp = time.time()
temp = add("obj", tempid, False)
objtree.item(temp, text=f"{x}:{y}")
#gamedata[temp]["args"]["ID"]
gamedata[temp]["args"]["char"] = " "
gamedata[temp]["name"] = f"{x}:{y}"
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "char", " ")
gamedata[temp]["args"]["position"] = hashengine.vector2(x, y)+offset
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "position", hashengine.vector2(x, y)+offset)
gamedata[temp]["args"]["anchored"] = True
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "anchored", True)
gamedata[temp]["args"]["collide"] = True
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "collide", True)
color = target.getpixel((x, y))
fcolor = hashengine.color3(color[0], color[1], color[2])
bcolor = hashengine.color3(color[0], color[1], color[2])
gamedata[temp]["args"]["fcolor"] = fcolor
gamedata[temp]["args"]["bcolor"] = bcolor
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "fcolor", fcolor)
setattr(preview.getobjbyid(gamedata[temp]["args"]["ID"]), "bcolor", bcolor)
#preview.render()
updselect(None)
tempwin.destroy()
def updselect(event):
preview.render()
selection = objtree.selection()
for selected in selection:
if "objsel" in objtree.item(selected, "tags"):
if gamedata[selected]["id"] == "obj":
preview._renderer.select(gamedata[selected]["args"]["position"].x+preview.camera.position.x, gamedata[selected]["args"]["position"].y+preview.camera.position.y)
if "HASHMODEL" in objtree.item(selected, "tags"):
for i in objtree.get_children(selected):
if "objsel" in objtree.item(i, "tags"):
if gamedata[i]["id"] == "obj":
preview._renderer.select(gamedata[i]["args"]["position"].x+preview.camera.position.x, gamedata[i]["args"]["position"].y+preview.camera.position.y)
def changegamex():
global gamexsize
gamexsize = int(aposx(gamexsize))
initpreview()
def changegamey():
global gameysize
gameysize = int(aposy(gameysize))
initpreview()
def initpreview():
global preview
objs = {}
try:
objs = preview._objects
preview._renderer.destroy()
ungridobjtrees()
except:
pass
preview = hashengine.game(renderer=lambda size, cam: previewrend(size, cam, container=container, offset=[0, 0]), sounddir="/", size=[gamexsize, gameysize])
preview._objects = objs
try:
gridobjtrees()
except NameError:
pass
def gridobjtrees():
objtree.grid(row=1, column=0)
atritree.grid(row=2, column=0)
def ungridobjtrees():
objtree.grid_remove()
atritree.grid_remove()
def loadplugins(GUIe=True):
global APIPLUG
print("loading plugins...")
for pluginname in os.listdir(plugindir):
if pluginname.split(".")[1] == "plg":
file = open(plugindir+"/"+pluginname, 'r')
plugindata = file.read()
plugindata = ast.literal_eval(plugindata)
print(plugindata["name"])
print("loading...")
installmodules(plugindata["modules"], True)
file.close()
if "init" in plugindata and GUIe == True:
exec(plugindata["init"], globals())
if "API" in plugindata:
APIPLUG.append(plugindata["API"])
if "run" in plugindata:
RUNPLUG.append(plugindata["run"])
print("done.")
return [APIPLUG, RUNPLUG]
def GUIinit():
global container
global objtree
global rmenu
global atritree
global currentat
global GUIe
global clog
global models
global menu
global filemenu
global addmenu
global testmenu
global buildmenu
global settings
global langmenu
models = []
GUIe = True
container = tk.Tk()
container.bind("<KeyPress>", updatepreviewcam, add="+")
global icons
icons = {}
for i in os.listdir("icons"):
icons[i.split(".")[0]] = tk.PhotoImage(file=f"icons/{i}")
#preview init
initpreview()
#tree init
objtree = tkk.Treeview(container, columns=("-"))
objtree.heading("#0", text=LH.string("objs"))
objtree.tag_bind("objsel", "<<TreeviewSelect>>", updatribute)
objtree.tag_bind("HASHMODEL", "<<TreeviewSelect>>", changemodelpos)
objtree.bind("<<TreeviewSelect>>", updselect, add="+")
objtree.grid(row=1, column=0)
#attribute tree init
currentat = "temp"
atritree = tkk.Treeview(container, columns=("#1"), selectmode="browse")
atritree.heading("#0", text=LH.string("attribute"))
atritree.heading("#1", text=LH.string("attribute-val"))
atritree.tag_bind("FA", "<Double-1>", halatribute)
atritree.tag_bind("OA", "<Double-1>", HMPC)
atritree.tag_bind("SID", "<Double-1>", copySID)
atritree.grid(row=2, column=0)
#right click menu
rmenu = tk.Menu(container, tearoff=0)
rmenu.add_command(label=LH.string("rename"), command=renameobj)
rmenu.add_command(label=LH.string("delete"), command=delobj)
rmenu.add_command(label=LH.string("modelobjs"), command=modelobjs)
rmenu.add_command(label=LH.string("demodelobjs"), command=demodelobjs)
objtree.bind("<Button-3>", rpopup)
#menu init
menu = tk.Menu(container)
container.config(menu=menu)
filemenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("file"), menu=filemenu)
filemenu.add_command(label=LH.string("new"), command=clear)
filemenu.add_command(label=LH.string("open"), command=load)
filemenu.add_command(label=LH.string("save"), command=save)
filemenu.add_separator()
#create logs var
clog = tk.BooleanVar()
filemenu.add_checkbutton(label=LH.string("clog"), onvalue=1, offvalue=0, variable=clog)
filemenu.add_separator()
filemenu.add_command(label=LH.string("export"), command=export)
filemenu.add_command(label=LH.string("import"), command=lambda: load(False))
filemenu.add_separator()
filemenu.add_command(label=LH.string("exit"), command=container.quit)
addmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("add"), menu=addmenu)
addmenu.add_command(label=LH.string("obj"), command=lambda: add("obj"))
addmenu.add_command(label=LH.string("script"), command=lambda: add("script"))
addmenu.add_command(label=LH.string("sound"), command=lambda: add("sound"))
addmenu.add_separator()
addmenu.add_command(label=LH.string("IPS"), command=importPS)
addmenu.add_command(label=LH.string("COBS"), command=lambda: COBS(acode(" ")))
addmenu.add_command(label=LH.string("COBI"), command=lambda: COBI(filedialog.askopenfilename()))
#addmenu.add_command(label=LH.string("obj"), command=lambda: muladd("obj"))
testmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("testing"), menu=testmenu)
testmenu.add_command(label=LH.string("test"), command=testing, image=icons["test"], compound="left")
testmenu.add_command(label=LH.string("stest"), command=stoptest, image=icons["stop-test"], compound="left")
buildmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("building"), menu=buildmenu)
buildmenu.add_command(label=LH.string("build"), command=build, image=icons["build"], compound="left")
settings = tk.Menu(menu)
menu.add_cascade(label=LH.string("settings"), menu=settings)
settings.add_command(label=LH.string("gamex"), command=changegamex)
settings.add_command(label=LH.string("gamey"), command=changegamey)
langmenu = tk.Menu(menu)
menu.add_cascade(label=LH.string("langs"), menu=langmenu)
for i in LH.getlangs():
langmenu.add_command(label=i, command=lambda i=i: selectlang(i))
container.mainloop()
# attribute changers
def ats(mode, old):
#mode 0 = string
#mode 1 = single character
out = easygui.enterbox(LH.string("newval"), LH.string("newval"))
if out:
if mode == 1 and len(out) != 1:
messagebox.showerror(LH.string("error"), LH.string("SCE"))
return "N"
return out
else:
return old
def anum(old):
out = easygui.enterbox(LH.string("newval"), LH.string("newval"))
if out:
if "." in out:
try:
out = float(out)
return out
except ValueError:
return old
else:
return int(out)
else:
return old
def abool(old):
out = easygui.boolbox(LH.string("newval"), LH.string("newval"), (LH.string("true"), LH.string("false")))
return out
def acode(old):
out = easygui.textbox(LH.string("newval"), LH.string("newval"), old)
if out:
return out
else:
return old
def apath(old, ext):
new = filedialog.askopenfilename(defaultextension=ext, filetypes=(ext))
if new:
return new
else:
return old
def aNULL(old):
return old
def aposdone():
global wait
wait = False
def aposx(old):
global wait
wait = True
temp = tk.Toplevel()
butframe = tk.Frame(temp)
currentvar = tk.DoubleVar(temp, value=old)
current = tk.Entry(temp, textvariable=currentvar)
current.grid(row=0)
b1 = tk.Button(butframe, image=icons["ar-left"], command=lambda: currentvar.set(currentvar.get()-1))
b2 = tk.Button(butframe, image=icons["ar-right"], command=lambda: currentvar.set(currentvar.get()+1))
b1.grid(row=0, column=0)
b2.grid(row=0, column=1)
butframe.grid(row=1)
b3 = tk.Button(temp, text=LH.string("done"), command=aposdone)
b3.grid(row=3)
while wait == True:
temp.update()
tempvar = currentvar.get()
temp.destroy()
numbers = list(string.digits)
numbers.append("-")
numbers.append(".")
for i in str(tempvar):
if not i in numbers:
return old
if str(tempvar).split(".")[1] == "0": return int(tempvar)
return tempvar
def aposy(old):
global wait
wait = True
temp = tk.Toplevel()
butframe = tk.Frame(temp)
currentvar = tk.DoubleVar(temp, value=old)
current = tk.Entry(temp, textvariable=currentvar)
current.grid(row=0)
b1 = tk.Button(butframe, image=icons["ar-up"], command=lambda: currentvar.set(currentvar.get()-1))
b2 = tk.Button(butframe, image=icons["ar-down"], command=lambda: currentvar.set(currentvar.get()+1))
b1.grid(row=0, column=0)
b2.grid(row=1, column=0)
butframe.grid(row=1)
b3 = tk.Button(temp, text=LH.string("done"), command=aposdone)
b3.grid(row=3)
while wait == True:
temp.update()
tempvar = currentvar.get()
temp.destroy()
numbers = list(string.digits)
numbers.append("-")
numbers.append(".")
for i in str(tempvar):
if not i in numbers:
return old
if str(tempvar).split(".")[1] == "0": return int(tempvar)
return tempvar
def execgame(gametree, shouldlog=True, fAPIPLUG=[], fRUNPLUG=[]):
global GUIe
global preview
global clog
global models
global APIPLUG
global RUNPLUG
APIPLUG = fAPIPLUG
RUNPLUG = fRUNPLUG
preview = hashengine.game(renderer=nullrend, sounddir="/")
GUIe = False
models = []
load(False, False, "", str(gametree))
clog = shouldlog
run()
def execcmd(target):
try:
exec(target, globals())
except Exception as e:
return e
def execlist(target):
for i in target:
print(f"> {i}")
execcmd(i)
def cmd():
print(f"hashengine version: {version}")
print("CMD")
print("running autoexecute commands...")
execlist(["threading.Thread(target=GUIinit).start()", "loadplugins()"])
if os.path.exists("autoexec"):
print("running custom autoexecute...")
execlist(["temp = open('autoexec', 'r')", "temp = temp.readlines()", "execlist(temp)"])
while True:
cmd = input("> ")
print(execcmd(cmd))
class rsound:
def __init__(self):
self.spath = ""
self.sdata = b""
class sound():
def __init__(self, new):
self.spath = os.path.basename(new).split(".")[0]
self.sdata = hashengine.loadsound(new)
global types
global ignoreat
global valtypes
global extypes
global attypes
global crucial
global DCTE
global gamexsize
global gameysize
global APIPLUG
global RUNPLUG
RUNPLUG = []
APIPLUG = []
gamexsize = 10
gameysize = 10
crucial = ["obj"]
types = hashengine.enum({"obj": hashengine.obj, "script": script, "rawsound": rsound, "sound": lambda: sound(apath("", [("Wave files", ".wave .wav")]))})
ignoreat = ["ID", "execute", "sdata"]
DCTE = ["code"]
"""self.position = vector2()
self.char = " "
self.ID = 0
self.gravity = 0
self.acceleration = vector2()
self.velocity = vector2()
self.friction = 0
self.collide = True
self.touch = True
self.anchored = False
self.bcolor = color3(255, 255, 255)
self.fcolor = color3()"""
valtypes = {
"char": lambda old: ats(1, old),
"gravity": anum,
"x": aposx, #anum
"y": aposy, #anum
"z": anum,
"r": anum,
"g": anum,
"b": anum,
"friction": anum,
"collide": abool,
"touch": abool,
"anchored": abool,
"code": acode,
"spath": aNULL,
}
#lambda old: apath(old, [("Wave files", ".wave .wav")])
extypes = list(valtypes.keys())
attypes = {
"vector2": hashengine.vector2,
"color3": hashengine.color3,
}
if __name__ == "__main__":
cmd()
stderrfile.close()