import logging
import os
from cgl.core.utils.general import current_user
from cgl.plugins.perforce.alchemy import check_connection
from cgl.plugins.perforce.utils.depot import depot_exists
from cgl.plugins.perforce.utils.git_operations import pull
from cgl.plugins.perforce.utils.workspace import create_workspace
from cgl.core.utils.general import remove_read_only_attribute, cgl_execute
from cgl.plugins.perforce.utils.config import (
get_server_ip,
get_port,
get_perforce_user_name,
)
from cgl.plugins.perforce.utils.depot import get_depot_name
from cgl.plugins.perforce.utils.workspace import get_workspace_name
from cgl.plugins.unreal.utils.uproject import get_uproject_path
[docs]
def setup_location_in_perforce(company, project, world):
"""
Sets up a workspace and pulls the world from the depot and opens it in unreal
Args:
project (str): Project the world belongs to
world (str): World to be opened
Returns:
True if the world was opened successfully, False if it was not
"""
if not check_connection():
logging.error("Not Connected to Perforce Server")
return False
if not depot_exists(company, project, world):
logging.error(
f"No Perforce Depot Found for {world}. Please seek the proper authorities to create one.(Tom)"
)
return False
if not create_workspace(company=company, project=project, location=world):
logging.error(f"Could Not Create Workspace for {project}_{world}")
return False
pull(company=company, project=project, location=world)
connect_unreal_to_perforce(company=company, project=project, world=world)
return True
[docs]
def connect_unreal_to_perforce(company, project, world):
"""
Args:
company (str): Company the world belongs to
project (str): Project the world belongs to
world (str): World to be opened
Returns:
True if the world was opened successfully, False if it was not
"""
uproject_path = get_uproject_path(company, project, world)
if not uproject_path:
logging.error("unable to find .uproject File {}".format(uproject_path))
return False
project_directory = os.path.dirname(uproject_path)
ip_address = get_server_ip()
port_ = get_port()
user_name = get_perforce_user_name()
workspace_name = get_workspace_name(company, project, world)
write_string = "[SourceControl.SourceControlSettings]\nProvider=Perforce\n\n[PerforceSourceControl.PerforceSourceControlSettings]\nPort={}:{}\nUserName={}\nWorkspace={}\nHostOverride=".format(
ip_address, port_, user_name, workspace_name
)
source_control_config_path = os.path.join(
project_directory,
"Saved",
"Config",
"WindowsEditor",
"SourceControlSettings.ini",
)
if not os.path.exists(os.path.dirname(source_control_config_path)):
os.makedirs(os.path.dirname(source_control_config_path))
if os.path.exists(source_control_config_path):
remove_read_only_attribute(source_control_config_path)
if not has_perforce_settings(source_control_config_path):
with open(source_control_config_path, "a+") as config_file:
config_file.write(write_string)
config_file.close()
[docs]
def has_perforce_settings(source_control_settings_filepath):
with open(source_control_settings_filepath, "a+") as settings:
for line in settings:
if "[PerforceSourceControl.PerforceSourceControlSettings]" in line:
return True
return False
[docs]
def commit():
"""
Commit all asset changes in the unreal project
"""
import unreal
unreal.EditorLoadingAndSavingUtils().save_dirty_packages(True, True)
[docs]
def push():
"""
Pushes all changes to perforce
"""
import unreal
changed_content_packages = (
unreal.EditorLoadingAndSavingUtils().get_dirty_content_packages()
)
changed_map_packages = unreal.EditorLoadingAndSavingUtils().get_dirty_map_packages()
all_changed_packages = changed_map_packages + changed_content_packages
description = "Automated Submit from Unreal Alchemy Plugin"
package_names = []
for package in all_changed_packages:
package_names.append(package.get_name())
commit()
unreal.SourceControl.check_in_files(package_names, description)
[docs]
def get_all_changed_files(project, world):
depot_name = get_depot_name(project, world)
workspace_name = get_workspace_name(project, world)
cmd = f"p4 opened -C {workspace_name} //{depot_name}/..."
result = cgl_execute(cmd, return_output=True)
# KEEPING MULTI USER CODE HERE IN CASE WE USE IT LATER
[docs]
def setup_multi_user(path_object):
"""
Function to set up MultiUserEditing settings for an unreal project
Args:
path_object (PathObject): Path object for the current uproject
Returns:
False if the settings were not set properly
"""
from cgl.plugins.unreal.utils.uproject import set_default_map
write_multi_user_settings(path_object)
write_udp_settings(path_object)
set_default_map(path_object)
[docs]
def write_multi_user_settings(path_object):
"""
Write settings for multi-user in current unreal project settings
Args:
path_object (cfg): Path object for the current unreal uproject
"""
port = get_multi_user_server_port(path_object)
username = current_user()
project_folder = os.path.dirname(path_object.perforce_workspace)
config_path = os.path.join(project_folder, "Config")
if not os.path.exists(config_path):
os.makedirs(config_path)
settings_file_path = os.path.join(config_path, "DefaultEngine.ini")
if os.path.exists(settings_file_path):
remove_read_only_attribute(settings_file_path)
settings_string = (
'[/Script/Concert.ConcertClientConfig]\nbInstallEditorToolbarButton=True\nClientSettings=(DisplayName="{}",AvatarColor=(R=1.000000,G=1.000000,B=1.000000,A=1.000000),DesktopAvatarActorClass=/ConcertSyncClient/DesktopPresence.DesktopPresence_C,VRAvatarActorClass=/ConcertSyncClient/VRPresence.VRPresence_C,ServerPort={},DiscoveryTimeoutSeconds=5,SessionTickFrequencySeconds=1,LatencyCompensationMs=0.000000,Tags=,ClientAuthenticationKey='
")\n\n".format(username, port)
)
logging.info(settings_string)
with open(settings_file_path, "a+") as f:
f.write(settings_string)
f.close()
[docs]
def write_udp_settings(path_object):
"""
Write udp messaging settings for current unreal project
Args:
path_object (PathObject): Path object for current uproject
Returns:
True if the settings were written successfully
"""
port = get_multi_user_server_port(path_object)
ip_address = get_server_ip(path_object)
project_folder = os.path.dirname(path_object.perforce_workspace)
config_path = os.path.join(project_folder, "Config")
if not os.path.exists(config_path):
os.makedirs(config_path)
settings_file_path = os.path.join(config_path, "DefaultEngine.ini")
if os.path.exists(settings_file_path):
remove_read_only_attribute(settings_file_path)
with open(settings_file_path, "a+") as f:
settings_string = (
"[/Script/UdpMessaging.UdpMessagingSettings]\nStaticEndpoints=%s:%s\n"
% (ip_address, port)
)
f.write(settings_string)
f.close()
return True
[docs]
def get_multi_user_server_port(path_object):
"""
Function to get the port used to access the Unreal Multi User Editor server
Args:
path_object (PathObject): Path object for the current uproject
Returns:
the port specified in company globals
"""
globals_ = path_object.cfg.project_config
port = globals_["templates"]["unreal"]["multiuser"]["port"]
return port