Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
OpenSimRegionConfig
#1
Anleitung zur Nutzung des Regionenkonfigurators

Hier ist eine Schritt-für-Schritt-Anleitung zur Verwendung des Python-Skripts, das eine GUI-Anwendung erstellt, um Regionskonfigurationen zu generieren.

### Voraussetzungen:
- **Python 3.x**: Stelle sicher, dass Python auf deinem System installiert ist.
- **Tkinter**: Tkinter ist normalerweise in Python vorinstalliert. Falls es fehlt, installiere es mit:
```bash
sudo apt-get install python3-tk
```

### 1. Überblick:
Dieses Skript erstellt eine grafische Benutzeroberfläche (GUI), mit der du verschiedene Einstellungen für Regionen vornehmen kannst, die anschließend in einer `.ini`-Konfigurationsdatei gespeichert werden. Jede Region hat verschiedene Parameter wie Größe, UUID, Position (Location) und viele andere, die du individuell konfigurieren kannst.

### 2. Skript ausführen:
1. **Python-Datei erstellen**: Erstelle eine Datei namens `region_config_app.py` und kopiere den bereitgestellten Python-Code in diese Datei.
2. **Skript starten**: Öffne ein Terminal oder eine Eingabeaufforderung und navigiere zu dem Verzeichnis, in dem sich die Datei befindet. Führe das Skript mit folgendem Befehl aus:
```bash
python region_config_app.py
```
3. **GUI-Anwendung**: Nach dem Ausführen öffnet sich ein Fenster mit der Benutzeroberfläche.

### 3. Verwendung der GUI:
1. **Felder ausfüllen**: Die Benutzeroberfläche zeigt verschiedene Felder an, in denen du die gewünschten Parameter für eine Region anpassen kannst.
- **Region Name**: Name der Region.
- **Region UUID**: Eindeutige Identifikationsnummer der Region.
- **Location**: Der Standort der Region (x, y), standardmäßig auf `1000,1000` gesetzt. Es wird automatisch angepasst, wenn du eine neue Region hinzufügst.
- **Size X, Y, Z**: Dimensionen der Region.
- **Internal Port**: Interner Netzwerkport.
- **External Host**: Externer Hostname.
- **Maptile UUID**: UUID für die Kartendatei, die die Region repräsentiert. Wird automatisch auf die Region UUID gesetzt.
- **Weitere Parameter**: Andere Einstellungen wie Maximalanzahl an Prims, Agenten, ScopeID usw.
2. **Region hinzufügen**: Klicke auf die Schaltfläche **"Add Region"**. Dadurch wird eine neue Region mit einer eigenen UUID und einem neuen Standort (basierend auf einer spiralförmigen Berechnung) erstellt.
3. **Konfiguration speichern**: Nachdem du die gewünschten Regionen hinzugefügt hast, klicke auf **"Save Config"**, um die Konfigurationen in einer `.ini`-Datei zu speichern. Wähle einen Speicherort und einen Dateinamen.

### 4. Ergebnis:
- Die erstellte `.ini`-Datei enthält Abschnitte für jede Region mit den von dir festgelegten Konfigurationen. Jede Region erhält eine eigene `Location`, `UUID` und andere Parameter.

### 5. Beispielhafte INI-Datei:
Die gespeicherte Datei könnte in etwa so aussehen:

```ini
PHP-Code:
[TestRegion_1]
RegionUUID 123e4567-e89b-12d3-a456-426614174000
Location 
1000,1000
SizeX 
256
SizeY 
256
SizeZ 
256
InternalPort 
9050
ExternalHostName 
SYSTEMIP
MaxPrims 
100000
MaxAgents 
99
MaptileStaticUUID 
123e4567-e89b-12d3-a456-426614174000
...

[
TestRegion_2]
RegionUUID 223e4567-e89b-12d3-a456-426614174001
Location 
1001,1001
SizeX 
256
SizeY 
256
SizeZ 
256
InternalPort 
9051
ExternalHostName 
SYSTEMIP
MaxPrims 
100000
MaxAgents 
99
MaptileStaticUUID 
223e4567-e89b-12d3-a456-426614174001 
...
```

### 6. Erweiterungen und Anpassungen:
Du kannst den Code anpassen, um zusätzliche Parameter hinzuzufügen oder die Art und Weise zu ändern, wie `Locations` berechnet werden.

### 7. Fehlerbehebung:
- **Tkinter nicht gefunden**: Stelle sicher, dass Tkinter installiert ist.
- **INI-Datei wird nicht gespeichert**: Überprüfe die Dateiberechtigungen im Zielverzeichnis.

Mit dieser Anleitung solltest du in der Lage sein, das Skript erfolgreich zu verwenden und benutzerdefinierte Konfigurationen für Regionen zu erstellen und zu verwalten.

Sourcecode:
PHP-Code:
import tkinter as tk
from tkinter import messagebox
filedialog
import configparser
import uuid
import math

class RegionConfigApp:
    
def __init__(selfroot):
        
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")
        
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_x tk.IntVar(value=256)
        
self.size_y tk.IntVar(value=256)
        
self.size_z 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="Mainland")
        
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  # Startet bei 0
        
self.angle 0
        self
.radius 1  # Initialer Radius
        
self.locations = []  # Liste für die Locations aller Regionen

        # 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.rootorient="vertical"command=canvas.yview)
        
scrollable_frame tk.Frame(canvas)

        
scrollable_frame.bind(
            
"<Configure>",
            
lambda ecanvas.configure(
                
scrollregion=canvas.bbox("all")
            )
        )

        
canvas.create_window((00), window=scrollable_frameanchor="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),  # Location field added here
            
("Size X:"self.size_x),
            (
"Size Y:"self.size_y),
            (
"Size Z:"self.size_z),
            (
"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_frametext=label_textvariable=var).grid(row=idxcolumn=0columnspan=2sticky=tk.Wpady=2padx=5)
            else:
                
tk.Label(scrollable_frametext=label_text).grid(row=idxcolumn=0sticky=tk.Wpady=2padx=5)
                
entry tk.Entry(scrollable_frametextvariable=var, width=40)
                
entry.grid(row=idxcolumn=1sticky=tk.Wpady=2padx=5)

        
button_frame tk.Frame(scrollable_frame)
        
button_frame.grid(row=len(fields), column=0columnspan=2pady=10)

        
tk.Button(button_frametext="Add Region"command=self.add_region).pack(side="left"padx=10)
        
tk.Button(button_frametext="Save Config"command=self.save_config).pack(side="left"padx=10)

    
def next_flower_spiral_location(self):
        
# Berechnung der nächsten Position in der spiralförmigen, blütenartigen Anordnung
        
self.angle += 137.5  # Goldener Winkel in Grad
        
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  # Erhöhe den Radius schrittweise für den nächsten Punkt
        
return location_xlocation_y

    def add_region
(self):
        
location self.next_flower_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()} hinzugefügt. Location: ({location[0]},{location[1]})")

    
def save_config(self):
        
filename filedialog.asksaveasfilename(defaultextension=".ini"filetypes=[("INI files""*.ini")])
        if 
filename:
            
config configparser.ConfigParser()

            for 
i in range(1self.region_count 1):
                if 
== 1:
                    
region_name self.region_name.get()
                    
region_uuid self.region_uuid.get()
                    
location_xlocation_y map(intself.location.get().split(','))  # Erste Region
                
else:
                    
region_name f"TestRegion_{i}"
                    
region_uuid str(uuid.uuid4())
                    
location_xlocation_y self.locations[i-1]  # Spezielle Location für jede Region

                
config[region_name] = {
                    
"RegionUUID"region_uuid,
                    
"Location"f"{location_x},{location_y}",
                    
"SizeX"self.size_x.get(),
                    
"SizeY"self.size_y.get(),
                    
"SizeZ"self.size_z.get(),
                    
"InternalPort"self.internal_port.get() + (1),
                    
"ExternalHostName"self.external_host.get(),
                    
"MaxPrims"self.max_prims.get(),
                    
"MaxAgents"self.max_agents.get(),
                    
"MaptileStaticUUID"self.maptile_uuid.get(),
                    
"InternalAddress"self.internal_address.get(),
                    
"AllowAlternatePorts"self.allow_alt_ports.get(),
                    
"NonPhysicalPrimMax"self.non_physical_prim_max.get(),
                    
"PhysicalPrimMax"self.physical_prim_max.get(),
                    
"ClampPrimSize"str(self.clamp_prim_size.get()),
                    
"MaxPrimsPerUser"self.max_prims_per_user.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("Gespeichert""Konfiguration erfolgreich gespeichert.")

if 
__name__ == "__main__":
    
root tk.Tk()
    
app RegionConfigApp(root)
    
root.mainloop() 
Sourcecode als Text:
.txt   OpenSimRegionConfig5.py.txt (Größe: 8,96 KB / Downloads: 40)
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



[-] The following 1 user says Thank You to Manfred Aabye for this post:
  • Dorena Verne
Zitieren
#2
Neue Version 5
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



[-] The following 1 user says Thank You to Manfred Aabye for this post:
  • Dorena Verne
Zitieren
#3
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
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(selfoptionstr):
        return 
optionstr  # Keep original case

class RegionConfigApp:
    
def __init__(selfroot):
        
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.rootorient="vertical"command=canvas.yview)
        
scrollable_frame tk.Frame(canvas)

        
scrollable_frame.bind(
            
"<Configure>",
            
lambda ecanvas.configure(
                
scrollregion=canvas.bbox("all")
            )
        )

        
canvas.create_window((00), window=scrollable_frameanchor="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_frametext=label_textvariable=var).grid(row=idxcolumn=0columnspan=2sticky=tk.Wpady=2padx=5)
            else:
                
tk.Label(scrollable_frametext=label_text).grid(row=idxcolumn=0sticky=tk.Wpady=2padx=5)
                
entry tk.Entry(scrollable_frametextvariable=var, width=40)
                
entry.grid(row=idxcolumn=1sticky=tk.Wpady=2padx=5)

        
# Dropdown for spiral selection
        
tk.Label(scrollable_frametext="Spiral Type:").grid(row=len(fields), column=0sticky=tk.Wpady=2padx=5)
        
spiral_menu tk.OptionMenu(scrollable_frameself.spiral_type"flower""fibonacci")
        
spiral_menu.grid(row=len(fields), column=1sticky=tk.Wpady=2padx=5)

        
button_frame tk.Frame(scrollable_frame)
        
button_frame.grid(row=len(fields) + 1column=0columnspan=2pady=10)

        
tk.Button(button_frametext="Add Region"command=self.add_region).pack(side="left"padx=10)
        
tk.Button(button_frametext="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_xlocation_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_xlocation_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(1self.region_count 1):
                if 
== 1:
                    
region_name self.region_name.get()
                    
region_uuid self.region_uuid.get()
                    
location_xlocation_y map(intself.location.get().split(','))  # First region
                
else:
                    
region_name f"TestRegion_{i}"
                    
region_uuid str(uuid.uuid4())
                    
location_xlocation_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() + (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() 


Angehängte Dateien
.txt   RegionConfigApp_06.py.txt (Größe: 10,06 KB / Downloads: 33)
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



Zitieren
#4
Anleitung zur Verwendung der RegionConfigApp

1. Programm starten
- Doppelklicken Sie auf die Programmdatei, um die RegionConfigApp zu starten. Ein Fenster mit dem Titel „Region Configurations“ öffnet sich.

2. Regionen hinzufügen
- Region Name: Geben Sie hier den Namen der Region ein. Der Name wird automatisch angepasst, wenn Sie eine neue Region hinzufügen (z.B. „TestRegion_1“).
- Region UUID: Eine eindeutige ID für die Region wird automatisch generiert und angezeigt.
- Location: Hier sehen Sie die aktuelle Position der Region auf der Karte. Diese wird automatisch aktualisiert, wenn Sie eine neue Region hinzufügen.
- Size: Geben Sie die Größe der Region ein. Diese Größe wird für alle Regionen verwendet.
- Internal Port: Der interne Port für die Region. Wird für jede neue Region automatisch um 1 erhöht.
- External Host: Der Hostname für die Region. Geben Sie hier die IP-Adresse oder den Domainnamen ein.
- Max Prims: Maximale Anzahl von Prim-Objekten (Objekten) in der Region.
- Max Agents: Maximale Anzahl von Agenten in der Region.
- Internal Address: Die interne IP-Adresse der Region.
- Allow Alternate Ports: Aktivieren Sie dieses Kontrollkästchen, wenn alternative Ports erlaubt sind.
- Non-Physical Prim Max: Maximale Anzahl nicht-physischer Prim-Objekte.
- Physical Prim Max: Maximale Anzahl physischer Prim-Objekte.
- Clamp Prim Size: Aktivieren Sie dieses Kontrollkästchen, um die Prim-Größe zu begrenzen.
- Max Prims Per User: Maximale Anzahl von Prim-Objekten pro Benutzer.
- Scope ID: Die ID des Bereichs oder der Region.
- Region Type: Der Typ der Region. Geben Sie hier den Typ ein.
- Render Min Height und Max Height: Geben Sie hier die Mindest- und Höhenausgabe in Metern an.
- Maptile Static File: Geben Sie den Namen der Datei ein, die für die Kartendarstellung verwendet wird.
- Master Avatar First Name und Last Name: Der Vorname und Nachname des Master-Avatars.
- Master Avatar Sandbox Password: Passwort für den Master-Avatar im Sandbox-Modus.

3. Spiral-Typ auswählen
- Spiral Type: Wählen Sie aus, ob die Region in einer „flower“- oder „fibonacci“-Spirale hinzugefügt werden soll. Nutzen Sie das Dropdown-Menü neben „Spiral Type“.

4. Region hinzufügen
- Add Region: Klicken Sie auf den Button „Add Region“, um eine neue Region hinzuzufügen. Die Position der neuen Region wird automatisch berechnet und angezeigt.

5. Konfiguration speichern
- Save Config: Klicken Sie auf den Button „Save Config“, um die aktuelle Konfiguration zu speichern. Ein Dialogfenster öffnet sich, in dem Sie den Speicherort und den Dateinamen für die Konfigurationsdatei auswählen können. Die Datei wird im `.ini`-Format gespeichert.

6. Fehlermeldungen und Hinweise
- Region Added: Nach dem Hinzufügen einer Region wird eine Bestätigungsmeldung angezeigt, die den Namen der Region und deren Position auf der Karte zeigt.
- Saved: Nach dem Speichern der Konfiguration wird eine Bestätigungsmeldung angezeigt.

---

Das war's! Mit diesen Schritten können Sie die RegionConfigApp effektiv nutzen, um Ihre Regionen zu konfigurieren und zu speichern.

P.S. MaxPrimsPerUser = -1 bedeutet unendlich, MaxPrimsPerUser = 100 Bedeutet jeder kann nur 100 Prims setzen/bauen.
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



[-] The following 1 user says Thank You to Manfred Aabye for this post:
  • Dorena Verne
Zitieren
#5
Schöner ist das aber mit Zufallsnamen statt Zahlen.

PHP-Code:
import tkinter as tk
from tkinter import messagebox
filedialog
import configparser
import uuid
import math
import random

# Erweiterte Listen mit Vorsilben und Nachsilben
VORSILBE = [
    
"Alt""Augs""Ber""Biele""Dort""Dres""Duel""Er""Frank""Gos",
    
"Gör""Heil""Hild""Jena""Kass""Kiel""Köln""Linz""Magde""Mann",
    
"Mar""Mittel""Neu""Nord""Ober""Osna""Ost""Reut""Rost""Sieger",
    
"Stutt""Sued""Unter""West""Neub""Stein""Zell""Trier""Hagen""Wert"
]

NACHSILBE = [
    
"markt""burg""lin""feld""mund""den""len""men""furt""lar",
    
"litz""bronn""heim""er""el""ken""Rhein""Delhi""Hessen""Bayern",
    
"Pfalz""brück""land""Harz""lingen""ock""land""gart""Baden"
    
"Tirol""Franken""Sachsen""Falen""ner""stein""stadt""bach""tal"
    
"hof""en""ring"
]

def generate_random_name():
    
# Wählt zufällig eine Vorsilbe und eine Nachsilbe aus
    
vorsilbe random.choice(VORSILBE)
    
nachsilbe random.choice(NACHSILBE)
    
    
# Generiert den Namen durch Verknüpfung der Vorsilbe und Nachsilbe
    
name vorsilbe nachsilbe
    
return name

# Custom ConfigParser class to preserve key case sensitivity
class CaseConfigParser(configparser.ConfigParser):
    
def optionxform(selfoptionstr):
        return 
optionstr  # Keep original case

class RegionConfigApp:
    
def __init__(selfroot):
        
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=generate_random_name())
        
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.rootorient="vertical"command=canvas.yview)
        
scrollable_frame tk.Frame(canvas)

        
scrollable_frame.bind(
            
"<Configure>",
            
lambda ecanvas.configure(
                
scrollregion=canvas.bbox("all")
            )
        )

        
canvas.create_window((00), window=scrollable_frameanchor="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_frametext=label_textvariable=var).grid(row=idxcolumn=0columnspan=2sticky=tk.Wpady=2padx=5)
            else:
                
tk.Label(scrollable_frametext=label_text).grid(row=idxcolumn=0sticky=tk.Wpady=2padx=5)
                
entry tk.Entry(scrollable_frametextvariable=var, width=40)
                
entry.grid(row=idxcolumn=1sticky=tk.Wpady=2padx=5)

        
# Dropdown for spiral selection
        
tk.Label(scrollable_frametext="Spiral Type:").grid(row=len(fields), column=0sticky=tk.Wpady=2padx=5)
        
spiral_menu tk.OptionMenu(scrollable_frameself.spiral_type"flower""fibonacci")
        
spiral_menu.grid(row=len(fields), column=1sticky=tk.Wpady=2padx=5)

        
button_frame tk.Frame(scrollable_frame)
        
button_frame.grid(row=len(fields) + 1column=0columnspan=2pady=10)

        
tk.Button(button_frametext="Add Region"command=self.add_region).pack(side="left"padx=10)
        
tk.Button(button_frametext="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_xlocation_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_xlocation_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(generate_random_name())
        
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(1self.region_count 1):
                if 
== 1:
                    
region_name self.region_name.get()
                    
region_uuid self.region_uuid.get()
                    
location_xlocation_y map(intself.location.get().split(','))  # First region
                
else:
                    
region_name generate_random_name()
                    
region_uuid str(uuid.uuid4())
                    
location_xlocation_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() + (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() 


Angehängte Dateien
.txt   RegionConfigApp_07.py.txt (Größe: 11,15 KB / Downloads: 24)
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



Zitieren
#6
Jetzt gibt es 14 Spirale-Typen.
Einige Fehler behoben.
Erste Windows Version verfügbar: DOWNLOAD

PHP-Code:
import tkinter as tk
from tkinter import messagebox
filedialog
import configparser
import uuid
import math
import random

# Erweiterte Listen mit Vorsilben und Nachsilben
VORSILBE = [
    
"Alt""Augs""Ber""Biele""Dort""Dres""Duel""Er""Frank""Gos",
    
"Gör""Heil""Hild""Jena""Kass""Kiel""Köln""Linz""Magde""Mann",
    
"Mar""Mittel""Neu""Nord""Ober""Osna""Ost""Reut""Rost""Sieger",
    
"Stutt""Sued""Unter""West""Neub""Stein""Zell""Trier""Hagen""Wert"
]

NACHSILBE = [
    
"markt""burg""lin""feld""mund""den""len""men""furt""lar",
    
"litz""bronn""heim""er""el""ken""Rhein""Delhi""Hessen""Bayern",
    
"Pfalz""brück""land""Harz""lingen""ock""land""gart""Baden"
    
"Tirol""Franken""Sachsen""Falen""ner""stein""stadt""bach""tal"
    
"hof""en""ring"
]

def generate_random_name():
    
# Wählt zufällig eine Vorsilbe und eine Nachsilbe aus
    
vorsilbe random.choice(VORSILBE)
    
nachsilbe random.choice(NACHSILBE)
    
    
# Generiert den Namen durch Verknüpfung der Vorsilbe und Nachsilbe
    
name vorsilbe nachsilbe
    
return name

# Custom ConfigParser class to preserve key case sensitivity
class CaseConfigParser(configparser.ConfigParser):
    
def optionxform(selfoptionstr):
        return 
optionstr  # Keep original case

class RegionConfigApp:
    
def __init__(selfroot):
        
self.root root

        self
.index 0

        
# Set window icon
        #self.root.iconbitmap("icon.ico")

        # Set window title
        
self.root.title("Region Configurations")

        
# Set window size
        
self.root.geometry("450x700")
        
        
# Initialize variables with default values
        
self.region_name tk.StringVar(value=generate_random_name())
        
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.rootorient="vertical"command=canvas.yview)
        
scrollable_frame tk.Frame(canvas)

        
scrollable_frame.bind(
            
"<Configure>",
            
lambda ecanvas.configure(
                
scrollregion=canvas.bbox("all")
            )
        )

        
canvas.create_window((00), window=scrollable_frameanchor="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_frametext=label_textvariable=var).grid(row=idxcolumn=0columnspan=2sticky=tk.Wpady=2padx=5)
            else:
                
tk.Label(scrollable_frametext=label_text).grid(row=idxcolumn=0sticky=tk.Wpady=2padx=5)
                
entry tk.Entry(scrollable_frametextvariable=var, width=40)
                
entry.grid(row=idxcolumn=1sticky=tk.Wpady=2padx=5)

        
# Dropdown for spiral selection
        
self.spiral_type tk.StringVar(value="flower"# Fix: Make sure the initial value of self.spiral_type is set correctly, which is already done with the line
        
tk.Label(scrollable_frametext="Spiral Type:").grid(row=len(fields), column=0sticky=tk.Wpady=2padx=5)
        
spiral_menu tk.OptionMenu(scrollable_frameself.spiral_type"archimedean_spiral1""archimedean_spiral2""circle1""circle2""fibonacci_spiral""flower""grid1""grid2""logarithmic_spiral""logistic""random1""random2""star")        
        
spiral_menu.grid(row=len(fields), column=1sticky=tk.Wpady=2padx=5)

        
button_frame tk.Frame(scrollable_frame)
        
button_frame.grid(row=len(fields) + 1column=0columnspan=2pady=10)

        
tk.Button(button_frametext="Add Region"command=self.add_region).pack(side="left"padx=10)
        
tk.Button(button_frametext="Save Config"command=self.save_config).pack(side="left"padx=10)

    
def next_flower_spiral_location1(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_xlocation_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_xlocation_y

    def next_archimedean_spiral_location2
(self):
        
self.angle += 10  # Increment angle by a fixed value
        
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 += 10  # Increment the radius linearly for a smooth spiral
        
return location_xlocation_y

    def next_logarithmic_spiral_location
(self):
        
self.angle += 10  # Increase angle gradually
        
radians math.radians(self.angle)
        
self.radius *= 1.1  # Exponentially increase the radius
        
location_x 1000 int(self.radius math.cos(radians))
        
location_y 1000 int(self.radius math.sin(radians))
        return 
location_xlocation_y

    def next_random_location1
(self):
        
location_x random.randint(02000)
        
location_y random.randint(02000)
        return 
location_xlocation_y

    def next_grid_location1
(self):
        
location_x 1000 + (self.index 10) * 100  # Move horizontally
        
location_y 1000 + (self.index // 10) * 100  # Move vertically
        
self.index += 1
        
return location_xlocation_y

    def next_circle_location1
(self):
        
self.angle += 36  # Divide 360 degrees by 10 points
        
radians math.radians(self.angle)
        
radius 500  # Constant radius
        
location_x 1000 int(radius math.cos(radians))
        
location_y 1000 int(radius math.sin(radians))
        return 
location_xlocation_y

    def next_star_location
(self):
        
self.angle += 144  # Star angle (5 points)
        
radians math.radians(self.angle)
        
location_x 1000 int(self.radius math.cos(radians))
        
location_y 1000 int(self.radius math.sin(radians))
        return 
location_xlocation_y

    def next_logistic_function_location
(self):
        
self.angle += 10
        radians 
math.radians(self.angle)
        
2000  # Carrying capacity (limit of growth)
        
location_x 1000 int(self.radius * (/ (math.exp(-0.1 self.angle))) * math.cos(radians))
        
location_y 1000 int(self.radius * (/ (math.exp(-0.1 self.angle))) * math.sin(radians))
        return 
location_xlocation_y

    def next_grid_location2
(self):
        
# Define grid parameters
        
grid_size 100  # Distance between grid points
        
num_columns 10  # Number of columns in the grid

        # Calculate row and column based on the current index
        
row self.index // num_columns
        
column self.index num_columns

        
# Calculate the x, y position
        
location_x 1000 column grid_size
        location_y 
1000 row grid_size

        
# Increment the index for the next call
        
self.index += 1

        
return location_xlocation_y

    def next_circle_location2
(self):
        
num_points 20  # Total number of points on the circle
        
radius 200  # Fixed radius of the circle

        # Calculate the angle for the current point
        
angle = (math.pi num_points) * self.index
        location_x 
1000 int(radius math.cos(angle))
        
location_y 1000 int(radius math.sin(angle))

        
# Increment the index for the next call
        
self.index += 1

        
return location_xlocation_y

    def next_archimedean_spiral_location1
(self):
        
# Increase the angle
        
self.angle += 10  # Change the step size for tighter or looser spirals
        
radians math.radians(self.angle)

        
# Archimedean spiral equation: r = a + b * theta
        
5  # Adjust this value for initial distance from the center
        
5  # Adjust for spacing between spiral arms
        
self.radius self.angle

        location_x 
1000 int(self.radius math.cos(radians))
        
location_y 1000 int(self.radius math.sin(radians))

        return 
location_xlocation_y

    def next_random_location2
(self):
        
# Define the bounds for random placement
        
location_x random.randint(8001200)
        
location_y random.randint(8001200)

        return 
location_xlocation_y

    def add_region
(self):
        
# Determine which spiral to use
        
location None
        
if self.spiral_type.get() == "flower":
            
location self.next_flower_spiral_location1()
        
elif self.spiral_type.get() == "fibonacci_spiral":
            
location self.next_fibonacci_spiral_location()
        
elif self.spiral_type.get() == "archimedean_spiral1":
            
location self.next_archimedean_spiral_location1()
        
elif self.spiral_type.get() == "logarithmic_spiral":
            
location self.next_logarithmic_spiral_location()
        
elif self.spiral_type.get() == "random1":
            
location self.next_random_location1()
        
elif self.spiral_type.get() == "grid1":
            
location self.next_grid_location1()
        
elif self.spiral_type.get() == "circle1":
            
location self.next_circle_location1()
        
elif self.spiral_type.get() == "logistic":
            
location self.next_logistic_function_location()
        
elif self.spiral_type.get() == "star":
            
location self.next_star_location()
        
elif self.spiral_type.get() == "grid2":
            
location self.next_grid_location2()
        
elif self.spiral_type.get() == "circle2":
            
location self.next_circle_location2()
        
elif self.spiral_type.get() == "archimedean_spiral2":
            
location self.next_archimedean_spiral_location2()
        
elif self.spiral_type.get() == "random2":
            
location self.next_random_location2()

        if 
location is None:
            
messagebox.showerror("Error""No spiral selected")
            return

        
self.locations.append(location)

        
new_uuid str(uuid.uuid4())

        
self.region_count += 1
        self
.region_name.set(generate_random_name())
        
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 
not filename:return
        if 
filename:
            
config CaseConfigParser()  # Use the custom parser to preserve case

            
for i in range(1self.region_count 1):
                if 
== 1:
                    
region_name self.region_name.get()
                    
region_uuid self.region_uuid.get()
                    
location_xlocation_y map(intself.location.get().split(','))  # First region
                
else:
                    
region_name generate_random_name()
                    
region_uuid str(uuid.uuid4())
                    
location_xlocation_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() + (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() 


Angehängte Dateien
.txt   RegionConfigApp_09.py.txt (Größe: 17,09 KB / Downloads: 31)
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



[-] The following 1 user says Thank You to Manfred Aabye for this post:
  • Dorena Verne
Zitieren
#7
Die nächste Version RegionConfigApp_10.py kann Regionen der Größe 256, 512, 768, 1024, 1280, 1536, 1792, 2048.
Gibt man einen falschen Wert ein, wird gerundet auf die nächste korrekte Größe.
Weitere Fehler wurden behoben.

Anleitung

RegionConfigApp_11.py

Windows-Release 2 Dateien Programm und Icon

Ist das toll, wenn plötzlich Sourcecode fehlt und Tabs und Leerzeichen so verändert werden, dass nichts mehr geht Smile
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



Zitieren
#8
Tooltips werden eingefügt:
RegionConfigApp_12.py
Ein Metaversum sind viele kleine Räume, die nahtlos aneinander passen,
sowie direkt sichtbar und begehbar sind, als wäre es aus einem Guss.



Zitieren


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste