15.09.2024, 10:15
(Dieser Beitrag wurde zuletzt bearbeitet: 15.09.2024, 10:49 von Manfred Aabye.)
Ich habe noch eine Funktion Fibonacci Anordnung eingefügt, dazu noch ein paar Fehler entfernt (Groß / Kleinschreibung).
Um eine Regionskonfiguration zu erstellen drückt bitte einmal "Add Region" dann "Save Config"
oder bei 5 neuen Konfigurationen 6-mal "Add Region" dann "Save Config",
bei 10 Regionen 11-mal "Add Region" dann "Save Config" etc. (Bug muss ich noch entfernen).
Die automatische anordnung funktioniert zur zeit nur mit 256er Regionen für 512, 768, 1024 etc. muss ich noch einfügen.
RegionConfigApp_06.py
Um eine Regionskonfiguration zu erstellen drückt bitte einmal "Add Region" dann "Save Config"
oder bei 5 neuen Konfigurationen 6-mal "Add Region" dann "Save Config",
bei 10 Regionen 11-mal "Add Region" dann "Save Config" etc. (Bug muss ich noch entfernen).
Die automatische anordnung funktioniert zur zeit nur mit 256er Regionen für 512, 768, 1024 etc. muss ich noch einfügen.
RegionConfigApp_06.py
PHP-Code:
import tkinter as tk
from tkinter import messagebox, filedialog
import configparser
import uuid
import math
# Custom ConfigParser class to preserve key case sensitivity
class CaseConfigParser(configparser.ConfigParser):
def optionxform(self, optionstr):
return optionstr # Keep original case
class RegionConfigApp:
def __init__(self, root):
self.root = root
self.root.title("Region Configurations")
# Set window size
self.root.geometry("450x700")
# Initialize variables with default values
self.region_name = tk.StringVar(value="TestRegion_1")
self.region_uuid = tk.StringVar(value=str(uuid.uuid4()))
self.maptile_uuid = tk.StringVar(value=self.region_uuid.get())
# Location variable for grid position
self.location = tk.StringVar(value="1000,1000")
self.size = tk.IntVar(value=256)
self.internal_port = tk.IntVar(value=9050)
self.external_host = tk.StringVar(value="SYSTEMIP")
self.max_prims = tk.IntVar(value=100000)
self.max_agents = tk.IntVar(value=99)
self.internal_address = tk.StringVar(value="0.0.0.0")
self.allow_alt_ports = tk.BooleanVar(value=False)
self.non_physical_prim_max = tk.IntVar(value=256)
self.physical_prim_max = tk.IntVar(value=64)
# New variables for additional settings
self.clamp_prim_size = tk.BooleanVar(value=False)
self.max_prims_per_user = tk.IntVar(value=-1)
self.scope_id = tk.StringVar(value=self.region_uuid.get())
self.region_type = tk.StringVar(value="")
self.render_min_height = tk.IntVar(value=-1)
self.render_max_height = tk.IntVar(value=100)
self.maptile_static_file = tk.StringVar(value="SomeFile.png")
self.master_avatar_first_name = tk.StringVar(value="John")
self.master_avatar_last_name = tk.StringVar(value="Doe")
self.master_avatar_sandbox_password = tk.StringVar(value="passwd")
self.region_count = 0 # Start at 0
self.angle = 0
self.radius = 1 # Initial radius for spirals
self.locations = [] # List to store locations of all regions
# Variable for selecting spiral type
self.spiral_type = tk.StringVar(value="flower") # Default to "flower"
# Trace changes to region_uuid to update maptile_uuid accordingly
self.region_uuid.trace_add('write', self.update_maptile_uuid)
# Build the UI
self.build_ui()
def update_maptile_uuid(self, *args):
self.maptile_uuid.set(self.region_uuid.get())
def build_ui(self):
canvas = tk.Canvas(self.root)
scrollbar = tk.Scrollbar(self.root, orient="vertical", command=canvas.yview)
scrollable_frame = tk.Frame(canvas)
scrollable_frame.bind(
"<Configure>",
lambda e: canvas.configure(
scrollregion=canvas.bbox("all")
)
)
canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
canvas.configure(yscrollcommand=scrollbar.set)
canvas.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
fields = [
("Region Name:", self.region_name),
("Region UUID:", self.region_uuid),
("Location:", self.location),
("Size:", self.size),
("Internal Port:", self.internal_port),
("External Host:", self.external_host),
("Max Prims:", self.max_prims),
("Max Agents:", self.max_agents),
("Maptile UUID:", self.maptile_uuid),
("Internal Address:", self.internal_address),
("Allow Alternate Ports:", self.allow_alt_ports),
("Non-Physical Prim Max:", self.non_physical_prim_max),
("Physical Prim Max:", self.physical_prim_max),
("Clamp Prim Size:", self.clamp_prim_size),
("Max Prims Per User:", self.max_prims_per_user),
("Scope ID:", self.scope_id),
("Region Type:", self.region_type),
("Render Min Height:", self.render_min_height),
("Render Max Height:", self.render_max_height),
("Maptile Static File:", self.maptile_static_file),
("Master Avatar First Name:", self.master_avatar_first_name),
("Master Avatar Last Name:", self.master_avatar_last_name),
("Master Avatar Sandbox Password:", self.master_avatar_sandbox_password),
]
for idx, (label_text, var) in enumerate(fields):
if isinstance(var, tk.BooleanVar):
tk.Checkbutton(scrollable_frame, text=label_text, variable=var).grid(row=idx, column=0, columnspan=2, sticky=tk.W, pady=2, padx=5)
else:
tk.Label(scrollable_frame, text=label_text).grid(row=idx, column=0, sticky=tk.W, pady=2, padx=5)
entry = tk.Entry(scrollable_frame, textvariable=var, width=40)
entry.grid(row=idx, column=1, sticky=tk.W, pady=2, padx=5)
# Dropdown for spiral selection
tk.Label(scrollable_frame, text="Spiral Type:").grid(row=len(fields), column=0, sticky=tk.W, pady=2, padx=5)
spiral_menu = tk.OptionMenu(scrollable_frame, self.spiral_type, "flower", "fibonacci")
spiral_menu.grid(row=len(fields), column=1, sticky=tk.W, pady=2, padx=5)
button_frame = tk.Frame(scrollable_frame)
button_frame.grid(row=len(fields) + 1, column=0, columnspan=2, pady=10)
tk.Button(button_frame, text="Add Region", command=self.add_region).pack(side="left", padx=10)
tk.Button(button_frame, text="Save Config", command=self.save_config).pack(side="left", padx=10)
def next_flower_spiral_location(self):
# Calculate the next position using a flower-like spiral
self.angle += 137.5 # Golden angle in degrees
radians = math.radians(self.angle)
location_x = 1000 + int(self.radius * math.cos(radians))
location_y = 1000 + int(self.radius * math.sin(radians))
self.radius += 1 # Increment the radius gradually for the next point
return location_x, location_y
def next_fibonacci_spiral_location(self):
# Calculate the next position using the Fibonacci spiral
self.angle += 137.5 # Golden angle in degrees
radians = math.radians(self.angle)
self.radius *= 1.618 # Fibonacci increment
location_x = 1000 + int(self.radius * math.cos(radians))
location_y = 1000 + int(self.radius * math.sin(radians))
return location_x, location_y
def add_region(self):
# Determine which spiral to use
if self.spiral_type.get() == "flower":
location = self.next_flower_spiral_location()
elif self.spiral_type.get() == "fibonacci":
location = self.next_fibonacci_spiral_location()
self.locations.append(location)
new_uuid = str(uuid.uuid4())
self.region_count += 1
self.region_name.set(f"TestRegion_{self.region_count}")
self.region_uuid.set(new_uuid)
self.internal_port.set(self.internal_port.get() + 1)
self.location.set(f"{location[0]},{location[1]}") # Update the location
messagebox.showinfo("Region Added", f"Region {self.region_name.get()} added. Location: ({location[0]},{location[1]})")
def save_config(self):
filename = filedialog.asksaveasfilename(defaultextension=".ini", filetypes=[("INI files", "*.ini")])
if filename:
config = CaseConfigParser() # Use the custom parser to preserve case
for i in range(1, self.region_count + 1):
if i == 1:
region_name = self.region_name.get()
region_uuid = self.region_uuid.get()
location_x, location_y = map(int, self.location.get().split(',')) # First region
else:
region_name = f"TestRegion_{i}"
region_uuid = str(uuid.uuid4())
location_x, location_y = self.locations[i-1] # Specific location for each region
config[region_name] = {
"RegionUUID": region_uuid,
"Location": f"{location_x},{location_y}",
"SizeX": self.size.get(),
"SizeY": self.size.get(),
"SizeZ": self.size.get(),
"InternalPort": self.internal_port.get() + (i - 1),
"InternalAddress": self.internal_address.get(),
"AllowAlternatePorts": str(self.allow_alt_ports.get()),
"ExternalHostName": self.external_host.get(),
"MaxPrims": self.max_prims.get(),
"MaxAgents": self.max_agents.get(),
"MaxPrimsPerUser": self.max_prims_per_user.get(),
";MaptileStaticUUID": self.maptile_uuid.get(),
";NonPhysicalPrimMax": self.non_physical_prim_max.get(),
";PhysicalPrimMax": self.physical_prim_max.get(),
";ClampPrimSize": str(self.clamp_prim_size.get()),
";ScopeID": self.scope_id.get(),
";RegionType": self.region_type.get(),
";RenderMinHeight": self.render_min_height.get(),
";RenderMaxHeight": self.render_max_height.get(),
";MaptileStaticFile": self.maptile_static_file.get(),
";MasterAvatarFirstName": self.master_avatar_first_name.get(),
";MasterAvatarLastName": self.master_avatar_last_name.get(),
";MasterAvatarSandboxPassword": self.master_avatar_sandbox_password.get(),
}
with open(filename, 'w') as configfile:
config.write(configfile)
messagebox.showinfo("Saved", "Configuration saved successfully.")
if __name__ == "__main__":
root = tk.Tk()
app = RegionConfigApp(root)
root.mainloop()
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.