Merge branch '49-connection-preset-system' into 'develop'
Connection-preset-system See merge request slumber/multi-user!121
This commit is contained in:
commit
f64db2155e
BIN
docs/getting_started/img/server_preset_exemple.gif
Normal file
BIN
docs/getting_started/img/server_preset_exemple.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 320 KiB |
BIN
docs/getting_started/img/server_preset_image_add.PNG
Normal file
BIN
docs/getting_started/img/server_preset_image_add.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.3 KiB |
BIN
docs/getting_started/img/server_preset_image_admin.PNG
Normal file
BIN
docs/getting_started/img/server_preset_image_admin.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
docs/getting_started/img/server_preset_image_normal_server.PNG
Normal file
BIN
docs/getting_started/img/server_preset_image_normal_server.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.0 KiB |
BIN
docs/getting_started/img/server_preset_image_report.PNG
Normal file
BIN
docs/getting_started/img/server_preset_image_report.PNG
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
@ -108,36 +108,69 @@ Before starting make sure that you have access to the session IP address and por
|
|||||||
1. Fill in your user information
|
1. Fill in your user information
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
|
||||||
Follow the user-info_ section for this step.
|
Joining a server
|
||||||
|
=======================
|
||||||
|
|
||||||
----------------
|
--------------
|
||||||
2. Network setup
|
Network setup
|
||||||
----------------
|
--------------
|
||||||
|
|
||||||
In the network panel, select **JOIN**.
|
In the network panel, select **JOIN**.
|
||||||
The **join sub-panel** (see image below) allows you to configure your client to join a
|
The **join sub-panel** (see image below) allows you to configure your client to join a
|
||||||
collaborative session which is already hosted.
|
collaborative session which is already hosted.
|
||||||
|
|
||||||
.. figure:: img/quickstart_join.png
|
.. figure:: img/server_preset_image_normal_server.png
|
||||||
:align: center
|
:align: center
|
||||||
:alt: Connect menu
|
:width: 200px
|
||||||
|
|
||||||
Connection panel
|
Connection pannel
|
||||||
|
|
||||||
Fill in the fields with your information:
|
Fill in the fields with your information:
|
||||||
|
|
||||||
- **IP**: the host's IP address.
|
- **IP**: the host's IP address.
|
||||||
- **Port**: the host's port number.
|
- **Port**: the host's port number.
|
||||||
- **Connect as admin**: connect yourself with **admin rights** (see :ref:`admin` ) to the session.
|
|
||||||
|
|
||||||
.. Maybe something more explicit here
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Additional configuration settings can be found in the :ref:`advanced` section.
|
|
||||||
|
|
||||||
Once you've configured every field, hit the button **CONNECT** to join the session !
|
Once you've configured every field, hit the button **CONNECT** to join the session !
|
||||||
When the :ref:`session-status` is **ONLINE** you are online and ready to start co-creating.
|
When the :ref:`session-status` is **ONLINE** you are online and ready to start co-creating.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you want to have **administrator rights** (see :ref:`admin` ) on the server, just enter the password created by the host in the **Connect as admin** section
|
||||||
|
|
||||||
|
.. figure:: img/server_preset_image_admin.png
|
||||||
|
:align: center
|
||||||
|
:width: 200px
|
||||||
|
|
||||||
|
Admin password
|
||||||
|
|
||||||
|
---------------
|
||||||
|
Server presets
|
||||||
|
---------------
|
||||||
|
|
||||||
|
You can save your server presets in a preset list below the 'JOIN' and 'HOST' buttons. This allows you to quickly access and manage your servers.
|
||||||
|
|
||||||
|
To add a server, first enter the ip address and the port (plus the password if needed), then click on the + icon to add a name to your preset. To remove a server from the list, select it and click on the - icon.
|
||||||
|
|
||||||
|
.. figure:: img/server_preset_exemple.gif
|
||||||
|
:align: center
|
||||||
|
:width: 200px
|
||||||
|
|
||||||
|
.. warning:: Be careful, if you don't rename your new preset, or if it has the same name as an existing preset, the old preset will be overwritten.
|
||||||
|
|
||||||
|
.. figure:: img/server_preset_image_report.png
|
||||||
|
:align: center
|
||||||
|
:width: 200px
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Two presets are already present when the addon is launched:
|
||||||
|
|
||||||
|
- The 'localhost' preset, to host and join a local session quickly
|
||||||
|
- The 'public session' preset, to join the public sessions of the multi-user server (official discord to participate : https://discord.gg/aBPvGws)
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Additional configuration settings can be found in the :ref:`advanced` section.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
When starting a **dedicated server**, the session status screen will take you to the **LOBBY**, awaiting an admin to start the session.
|
When starting a **dedicated server**, the session status screen will take you to the **LOBBY**, awaiting an admin to start the session.
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ Hit 'Create a network'(see image below) and go to the network settings.
|
|||||||
:align: center
|
:align: center
|
||||||
:width: 450px
|
:width: 450px
|
||||||
|
|
||||||
Network page
|
Admin password
|
||||||
|
|
||||||
Now that the network is created, let's configure it.
|
Now that the network is created, let's configure it.
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 8c27d0cec6b7db1756a7d142c94023fe20f352ff
|
Subproject commit b2bd39a6e140f60fc2422d710bce83586cc93af1
|
@ -34,6 +34,8 @@ from queue import Queue
|
|||||||
from time import gmtime, strftime
|
from time import gmtime, strftime
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from bpy.props import FloatProperty
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import _pickle as pickle
|
import _pickle as pickle
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -161,7 +163,7 @@ class SessionStartOperator(bpy.types.Operator):
|
|||||||
settings = utils.get_preferences()
|
settings = utils.get_preferences()
|
||||||
runtime_settings = context.window_manager.session
|
runtime_settings = context.window_manager.session
|
||||||
users = bpy.data.window_managers['WinMan'].online_users
|
users = bpy.data.window_managers['WinMan'].online_users
|
||||||
admin_pass = runtime_settings.password
|
admin_pass = settings.password
|
||||||
|
|
||||||
users.clear()
|
users.clear()
|
||||||
deleyables.clear()
|
deleyables.clear()
|
||||||
@ -902,6 +904,76 @@ class SessionLoadSaveOperator(bpy.types.Operator, ImportHelper):
|
|||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
class SessionPresetServerAdd(bpy.types.Operator):
|
||||||
|
"""Add a server to the server list preset"""
|
||||||
|
bl_idname = "session.preset_server_add"
|
||||||
|
bl_label = "add server preset"
|
||||||
|
bl_description = "add the current server to the server preset list"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
name : bpy.props.StringProperty(default="server_preset")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
assert(context)
|
||||||
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
settings = utils.get_preferences()
|
||||||
|
|
||||||
|
col.prop(settings, "server_name", text="server name")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
assert(context)
|
||||||
|
|
||||||
|
settings = utils.get_preferences()
|
||||||
|
|
||||||
|
existing_preset = settings.server_preset.get(settings.server_name)
|
||||||
|
|
||||||
|
new_server = existing_preset if existing_preset else settings.server_preset.add()
|
||||||
|
new_server.name = settings.server_name
|
||||||
|
new_server.server_ip = settings.ip
|
||||||
|
new_server.server_port = settings.port
|
||||||
|
new_server.server_password = settings.password
|
||||||
|
|
||||||
|
settings.server_preset_interface = settings.server_name
|
||||||
|
|
||||||
|
if new_server == existing_preset :
|
||||||
|
self.report({'INFO'}, "Server '" + settings.server_name + "' override")
|
||||||
|
else :
|
||||||
|
self.report({'INFO'}, "New '" + settings.server_name + "' server preset")
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class SessionPresetServerRemove(bpy.types.Operator):
|
||||||
|
"""Remove a server to the server list preset"""
|
||||||
|
bl_idname = "session.preset_server_remove"
|
||||||
|
bl_label = "remove server preset"
|
||||||
|
bl_description = "remove the current server from the server preset list"
|
||||||
|
bl_options = {"REGISTER"}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
assert(context)
|
||||||
|
|
||||||
|
settings = utils.get_preferences()
|
||||||
|
|
||||||
|
settings.server_preset.remove(settings.server_preset.find(settings.server_preset_interface))
|
||||||
|
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def menu_func_import(self, context):
|
def menu_func_import(self, context):
|
||||||
self.layout.operator(SessionLoadSaveOperator.bl_idname, text='Multi-user session snapshot (.db)')
|
self.layout.operator(SessionLoadSaveOperator.bl_idname, text='Multi-user session snapshot (.db)')
|
||||||
|
|
||||||
@ -924,6 +996,8 @@ classes = (
|
|||||||
SessionLoadSaveOperator,
|
SessionLoadSaveOperator,
|
||||||
SessionStopAutoSaveOperator,
|
SessionStopAutoSaveOperator,
|
||||||
SessionPurgeOperator,
|
SessionPurgeOperator,
|
||||||
|
SessionPresetServerAdd,
|
||||||
|
SessionPresetServerRemove,
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_external_dependencies():
|
def update_external_dependencies():
|
||||||
|
@ -33,6 +33,19 @@ from replication.interface import session
|
|||||||
IP_REGEX = re.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
|
IP_REGEX = re.compile("^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
|
||||||
HOSTNAME_REGEX = re.compile("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$")
|
HOSTNAME_REGEX = re.compile("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$")
|
||||||
|
|
||||||
|
DEFAULT_PRESETS = {
|
||||||
|
"localhost" : {
|
||||||
|
"server_ip": "localhost",
|
||||||
|
"server_port": 5555,
|
||||||
|
"server_password": "admin"
|
||||||
|
},
|
||||||
|
"public session" : {
|
||||||
|
"server_ip": "51.75.71.183",
|
||||||
|
"server_port": 5555,
|
||||||
|
"server_password": ""
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
def randomColor():
|
def randomColor():
|
||||||
"""Generate a random color """
|
"""Generate a random color """
|
||||||
r = random.random()
|
r = random.random()
|
||||||
@ -65,8 +78,11 @@ def update_ip(self, context):
|
|||||||
logging.error("Wrong IP format")
|
logging.error("Wrong IP format")
|
||||||
self['ip'] = "127.0.0.1"
|
self['ip'] = "127.0.0.1"
|
||||||
|
|
||||||
|
def update_server_preset_interface(self, context):
|
||||||
|
self.server_name = self.server_preset.get(self.server_preset_interface).name
|
||||||
|
self.ip = self.server_preset.get(self.server_preset_interface).server_ip
|
||||||
|
self.port = self.server_preset.get(self.server_preset_interface).server_port
|
||||||
|
self.password = self.server_preset.get(self.server_preset_interface).server_password
|
||||||
|
|
||||||
def update_directory(self, context):
|
def update_directory(self, context):
|
||||||
new_dir = Path(self.cache_directory)
|
new_dir = Path(self.cache_directory)
|
||||||
@ -93,6 +109,10 @@ class ReplicatedDatablock(bpy.types.PropertyGroup):
|
|||||||
auto_push: bpy.props.BoolProperty(default=True)
|
auto_push: bpy.props.BoolProperty(default=True)
|
||||||
icon: bpy.props.StringProperty()
|
icon: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
class ServerPreset(bpy.types.PropertyGroup):
|
||||||
|
server_ip: bpy.props.StringProperty()
|
||||||
|
server_port: bpy.props.IntProperty(default=5555)
|
||||||
|
server_password: bpy.props.StringProperty(default="admin", subtype = "PASSWORD")
|
||||||
|
|
||||||
def set_sync_render_settings(self, value):
|
def set_sync_render_settings(self, value):
|
||||||
self['sync_render_settings'] = value
|
self['sync_render_settings'] = value
|
||||||
@ -145,7 +165,7 @@ class SessionPrefs(bpy.types.AddonPreferences):
|
|||||||
ip: bpy.props.StringProperty(
|
ip: bpy.props.StringProperty(
|
||||||
name="ip",
|
name="ip",
|
||||||
description='Distant host ip',
|
description='Distant host ip',
|
||||||
default="127.0.0.1",
|
default="localhost",
|
||||||
update=update_ip)
|
update=update_ip)
|
||||||
username: bpy.props.StringProperty(
|
username: bpy.props.StringProperty(
|
||||||
name="Username",
|
name="Username",
|
||||||
@ -160,6 +180,17 @@ class SessionPrefs(bpy.types.AddonPreferences):
|
|||||||
description='Distant host port',
|
description='Distant host port',
|
||||||
default=5555
|
default=5555
|
||||||
)
|
)
|
||||||
|
server_name: bpy.props.StringProperty(
|
||||||
|
name="server_name",
|
||||||
|
description="Custom name of the server",
|
||||||
|
default='localhost',
|
||||||
|
)
|
||||||
|
password: bpy.props.StringProperty(
|
||||||
|
name="password",
|
||||||
|
default=random_string_digits(),
|
||||||
|
description='Session password',
|
||||||
|
subtype='PASSWORD'
|
||||||
|
)
|
||||||
sync_flags: bpy.props.PointerProperty(
|
sync_flags: bpy.props.PointerProperty(
|
||||||
type=ReplicationFlags
|
type=ReplicationFlags
|
||||||
)
|
)
|
||||||
@ -321,6 +352,25 @@ class SessionPrefs(bpy.types.AddonPreferences):
|
|||||||
max=59
|
max=59
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Server preset
|
||||||
|
def server_list_callback(scene, context):
|
||||||
|
settings = get_preferences()
|
||||||
|
enum = []
|
||||||
|
for i in settings.server_preset:
|
||||||
|
enum.append((i.name, i.name, ""))
|
||||||
|
return enum
|
||||||
|
|
||||||
|
server_preset: bpy.props.CollectionProperty(
|
||||||
|
name="server preset",
|
||||||
|
type=ServerPreset,
|
||||||
|
)
|
||||||
|
server_preset_interface: bpy.props.EnumProperty(
|
||||||
|
name="servers",
|
||||||
|
description="servers enum",
|
||||||
|
items=server_list_callback,
|
||||||
|
update=update_server_preset_interface,
|
||||||
|
)
|
||||||
|
|
||||||
# Custom panel
|
# Custom panel
|
||||||
panel_category: bpy.props.StringProperty(
|
panel_category: bpy.props.StringProperty(
|
||||||
description="Choose a name for the category of the panel",
|
description="Choose a name for the category of the panel",
|
||||||
@ -420,6 +470,18 @@ class SessionPrefs(bpy.types.AddonPreferences):
|
|||||||
new_db.icon = type_module_class.bl_icon
|
new_db.icon = type_module_class.bl_icon
|
||||||
new_db.bl_name = type_module_class.bl_id
|
new_db.bl_name = type_module_class.bl_id
|
||||||
|
|
||||||
|
# custom at launch server preset
|
||||||
|
def generate_default_presets(self):
|
||||||
|
for preset_name, preset_data in DEFAULT_PRESETS.items():
|
||||||
|
existing_preset = self.server_preset.get(preset_name)
|
||||||
|
if existing_preset :
|
||||||
|
continue
|
||||||
|
new_server = self.server_preset.add()
|
||||||
|
new_server.name = preset_name
|
||||||
|
new_server.server_ip = preset_data.get('server_ip')
|
||||||
|
new_server.server_port = preset_data.get('server_port')
|
||||||
|
new_server.server_password = preset_data.get('server_password',None)
|
||||||
|
|
||||||
|
|
||||||
def client_list_callback(scene, context):
|
def client_list_callback(scene, context):
|
||||||
from . import operators
|
from . import operators
|
||||||
@ -496,12 +558,6 @@ class SessionProps(bpy.types.PropertyGroup):
|
|||||||
description='Connect as admin',
|
description='Connect as admin',
|
||||||
default=False
|
default=False
|
||||||
)
|
)
|
||||||
password: bpy.props.StringProperty(
|
|
||||||
name="password",
|
|
||||||
default=random_string_digits(),
|
|
||||||
description='Session password',
|
|
||||||
subtype='PASSWORD'
|
|
||||||
)
|
|
||||||
internet_ip: bpy.props.StringProperty(
|
internet_ip: bpy.props.StringProperty(
|
||||||
name="internet ip",
|
name="internet ip",
|
||||||
default="no found",
|
default="no found",
|
||||||
@ -523,6 +579,7 @@ classes = (
|
|||||||
SessionProps,
|
SessionProps,
|
||||||
ReplicationFlags,
|
ReplicationFlags,
|
||||||
ReplicatedDatablock,
|
ReplicatedDatablock,
|
||||||
|
ServerPreset,
|
||||||
SessionPrefs,
|
SessionPrefs,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -538,6 +595,10 @@ def register():
|
|||||||
logging.debug('Generating bl_types preferences')
|
logging.debug('Generating bl_types preferences')
|
||||||
prefs.generate_supported_types()
|
prefs.generate_supported_types()
|
||||||
|
|
||||||
|
# at launch server presets
|
||||||
|
prefs.generate_default_presets()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
from bpy.utils import unregister_class
|
from bpy.utils import unregister_class
|
||||||
|
@ -157,6 +157,12 @@ class SESSION_PT_settings_network(bpy.types.Panel):
|
|||||||
row.prop(runtime_settings, "session_mode", expand=True)
|
row.prop(runtime_settings, "session_mode", expand=True)
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
|
|
||||||
|
col = row.row(align=True)
|
||||||
|
col.prop(settings, "server_preset_interface", text="")
|
||||||
|
col.operator("session.preset_server_add", icon='ADD', text="")
|
||||||
|
col.operator("session.preset_server_remove", icon='REMOVE', text="")
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
box = row.box()
|
box = row.box()
|
||||||
|
|
||||||
if runtime_settings.session_mode == 'HOST':
|
if runtime_settings.session_mode == 'HOST':
|
||||||
@ -168,7 +174,7 @@ class SESSION_PT_settings_network(bpy.types.Panel):
|
|||||||
row.prop(settings, "init_method", text="")
|
row.prop(settings, "init_method", text="")
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text="Admin password:")
|
row.label(text="Admin password:")
|
||||||
row.prop(runtime_settings, "password", text="")
|
row.prop(settings, "password", text="")
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.operator("session.start", text="HOST").host = True
|
row.operator("session.start", text="HOST").host = True
|
||||||
else:
|
else:
|
||||||
@ -184,11 +190,10 @@ class SESSION_PT_settings_network(bpy.types.Panel):
|
|||||||
if runtime_settings.admin:
|
if runtime_settings.admin:
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.label(text="Password:")
|
row.label(text="Password:")
|
||||||
row.prop(runtime_settings, "password", text="")
|
row.prop(settings, "password", text="")
|
||||||
row = box.row()
|
row = box.row()
|
||||||
row.operator("session.start", text="CONNECT").host = False
|
row.operator("session.start", text="CONNECT").host = False
|
||||||
|
|
||||||
|
|
||||||
class SESSION_PT_settings_user(bpy.types.Panel):
|
class SESSION_PT_settings_user(bpy.types.Panel):
|
||||||
bl_idname = "MULTIUSER_SETTINGS_USER_PT_panel"
|
bl_idname = "MULTIUSER_SETTINGS_USER_PT_panel"
|
||||||
bl_label = "User info"
|
bl_label = "User info"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user