1445 lines
53 KiB
C#
1445 lines
53 KiB
C#
/*
|
|
* FILE: EC_Configs.cs
|
|
*
|
|
* DESCRIPTION: Configuration management for game client
|
|
*
|
|
* CONVERTED FROM: EC_Configs.cpp/EC_Configs.h
|
|
*
|
|
* Copyright (c) 2004 Archosaur Studio, All Rights Reserved.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
// Constants
|
|
public static class EC_ConfigConstants
|
|
{
|
|
public const int EC_AUTOREPLY_LEN = 64;
|
|
public const int EC_BLACKLIST_LEN = 20;
|
|
public const int EC_USERCHANNEL_NUM = 6;
|
|
public const int EC_COMBOSKILL_NUM = 8;
|
|
public const int EC_COMBOSKILL_LEN = 8;
|
|
public const int EC_CONFIG_VERSION = 36;
|
|
public const int DEFAULT_UI_THEME_ID = 0;
|
|
}
|
|
|
|
// System Settings Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_SYSTEM_SETTING
|
|
{
|
|
public byte nLevel;
|
|
public byte nSight;
|
|
public byte nWaterEffect;
|
|
public bool bSimpleTerrain;
|
|
public byte nTreeDetail;
|
|
public byte nGrassDetail;
|
|
public byte nCloudDetail;
|
|
public bool bShadow;
|
|
public bool bMipMapBias;
|
|
public bool bFullGlow;
|
|
public bool bSpaceWarp;
|
|
public bool bSunFlare;
|
|
public bool bAdvancedWater;
|
|
public byte nSoundVol;
|
|
public byte nMusicVol;
|
|
public int iGamma;
|
|
public int iRndWidth;
|
|
public int iRndHeight;
|
|
public int iTexDetail;
|
|
public int iSoundQuality;
|
|
public bool bFullScreen;
|
|
public bool bWideScreen;
|
|
public bool bVSync;
|
|
public bool bScaleUI;
|
|
public int iTheme;
|
|
|
|
public void Reset()
|
|
{
|
|
nLevel = 0;
|
|
nSight = 0;
|
|
nWaterEffect = 0;
|
|
bSimpleTerrain = true;
|
|
nTreeDetail = 0;
|
|
nGrassDetail = 0;
|
|
nCloudDetail = 0;
|
|
bShadow = false;
|
|
bMipMapBias = false;
|
|
bFullGlow = false;
|
|
bSpaceWarp = false;
|
|
bSunFlare = false;
|
|
bAdvancedWater = false;
|
|
nSoundVol = 100;
|
|
nMusicVol = 100;
|
|
iGamma = 41;
|
|
iRndWidth = 800;
|
|
iRndHeight = 600;
|
|
iTexDetail = 2;
|
|
iSoundQuality = 2;
|
|
bFullScreen = true;
|
|
bWideScreen = false;
|
|
bVSync = true;
|
|
bScaleUI = false;
|
|
iTheme = EC_ConfigConstants.DEFAULT_UI_THEME_ID;
|
|
}
|
|
}
|
|
|
|
// Combo Skill Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_COMBOSKILL
|
|
{
|
|
public byte nIcon;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = EC_ConfigConstants.EC_COMBOSKILL_LEN)]
|
|
public short[] idSkill;
|
|
|
|
public EC_COMBOSKILL(bool initialize)
|
|
{
|
|
nIcon = 0;
|
|
idSkill = new short[EC_ConfigConstants.EC_COMBOSKILL_LEN];
|
|
}
|
|
|
|
public bool Clear(int id)
|
|
{
|
|
bool bClear = false;
|
|
for (int i = 0; i < EC_ConfigConstants.EC_COMBOSKILL_LEN; ++i)
|
|
{
|
|
if (idSkill[i] == id)
|
|
{
|
|
idSkill[i] = 0;
|
|
bClear = true;
|
|
}
|
|
}
|
|
return bClear;
|
|
}
|
|
}
|
|
|
|
// Video Settings Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_VIDEO_SETTING
|
|
{
|
|
public bool bPlayerHP;
|
|
public bool bPlayerMP;
|
|
public bool bPlayerEXP;
|
|
public bool bPlayerHeadText;
|
|
public bool bPlayerName;
|
|
public bool bPlayerFaction;
|
|
public bool bPlayerTitle;
|
|
public bool bPlayerShop;
|
|
public bool bPlayerSelfName;
|
|
public bool bPlayerTalk;
|
|
public bool bPlayerBubble;
|
|
public bool bMonsterName;
|
|
public bool bNPCName;
|
|
public bool bGoodsName;
|
|
public bool bModelLimit;
|
|
public byte nDistance;
|
|
public bool bMapMonster;
|
|
public bool bMapNPC;
|
|
public bool bMapPlayer;
|
|
public byte nEffect;
|
|
public bool bShowCustomize;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = EC_ConfigConstants.EC_COMBOSKILL_NUM)]
|
|
public EC_COMBOSKILL[] comboSkill;
|
|
public bool bPlayerForce;
|
|
public bool bMailToFriendsRemind;
|
|
public int iMailToFriendsCheckTime;
|
|
public char cTabSelType;
|
|
public bool bActivityRemind;
|
|
public int ibActivityReminderCheckTime;
|
|
public bool bCloseMeridiansHint;
|
|
|
|
public void Reset()
|
|
{
|
|
bPlayerHP = false;
|
|
bPlayerMP = false;
|
|
bPlayerEXP = false;
|
|
bPlayerHeadText = true;
|
|
bPlayerName = true;
|
|
bPlayerFaction = true;
|
|
bPlayerTitle = true;
|
|
bPlayerShop = true;
|
|
bPlayerSelfName = true;
|
|
bPlayerTalk = true;
|
|
bPlayerBubble = false;
|
|
bMonsterName = true;
|
|
bNPCName = true;
|
|
bGoodsName = true;
|
|
bModelLimit = false;
|
|
nDistance = 50;
|
|
bMapMonster = false;
|
|
bMapNPC = true;
|
|
bMapPlayer = true;
|
|
nEffect = 4;
|
|
bShowCustomize = true;
|
|
bPlayerForce = true;
|
|
bMailToFriendsRemind = true;
|
|
iMailToFriendsCheckTime = 0;
|
|
bActivityRemind = true;
|
|
ibActivityReminderCheckTime = 0;
|
|
cTabSelType = (char)0;
|
|
bCloseMeridiansHint = false;
|
|
|
|
comboSkill = new EC_COMBOSKILL[EC_ConfigConstants.EC_COMBOSKILL_NUM];
|
|
for (int i = 0; i < EC_ConfigConstants.EC_COMBOSKILL_NUM; i++)
|
|
{
|
|
comboSkill[i] = new EC_COMBOSKILL(true);
|
|
comboSkill[i].nIcon = 0;
|
|
}
|
|
}
|
|
|
|
public void Read(BinaryReader reader, uint dwVer)
|
|
{
|
|
Reset();
|
|
|
|
if (dwVer < 15) return;
|
|
|
|
bPlayerHP = reader.ReadBoolean();
|
|
bPlayerMP = reader.ReadBoolean();
|
|
bPlayerEXP = reader.ReadBoolean();
|
|
bPlayerHeadText = reader.ReadBoolean();
|
|
bPlayerName = reader.ReadBoolean();
|
|
bPlayerFaction = reader.ReadBoolean();
|
|
bPlayerTitle = reader.ReadBoolean();
|
|
bPlayerShop = reader.ReadBoolean();
|
|
bPlayerSelfName = reader.ReadBoolean();
|
|
bPlayerTalk = reader.ReadBoolean();
|
|
bPlayerBubble = reader.ReadBoolean();
|
|
bMonsterName = reader.ReadBoolean();
|
|
bNPCName = reader.ReadBoolean();
|
|
bGoodsName = reader.ReadBoolean();
|
|
bModelLimit = reader.ReadBoolean();
|
|
nDistance = reader.ReadByte();
|
|
bMapMonster = reader.ReadBoolean();
|
|
bMapNPC = reader.ReadBoolean();
|
|
bMapPlayer = reader.ReadBoolean();
|
|
nEffect = reader.ReadByte();
|
|
bShowCustomize = reader.ReadBoolean();
|
|
|
|
for (int i = 0; i < EC_ConfigConstants.EC_COMBOSKILL_NUM; i++)
|
|
{
|
|
comboSkill[i].nIcon = reader.ReadByte();
|
|
for (int j = 0; j < EC_ConfigConstants.EC_COMBOSKILL_LEN; j++)
|
|
{
|
|
comboSkill[i].idSkill[j] = reader.ReadInt16();
|
|
}
|
|
}
|
|
|
|
if (dwVer >= 21)
|
|
bPlayerForce = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 22)
|
|
{
|
|
bMailToFriendsRemind = reader.ReadBoolean();
|
|
iMailToFriendsCheckTime = reader.ReadInt32();
|
|
}
|
|
|
|
if (dwVer >= 24)
|
|
cTabSelType = reader.ReadChar();
|
|
|
|
if (dwVer >= 28)
|
|
{
|
|
bActivityRemind = reader.ReadBoolean();
|
|
ibActivityReminderCheckTime = reader.ReadInt32();
|
|
}
|
|
|
|
if (dwVer >= 31)
|
|
bCloseMeridiansHint = reader.ReadBoolean();
|
|
}
|
|
}
|
|
|
|
// Game Settings Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_GAME_SETTING
|
|
{
|
|
public bool bNoTeamRequest;
|
|
public bool bNoTradeRequest;
|
|
public bool bTurnaround;
|
|
public bool bReverseWheel;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = EC_ConfigConstants.EC_USERCHANNEL_NUM * 15)] // GP_CHAT_MAX = 15
|
|
public bool[] bChannel;
|
|
public bool bAutoReply;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = EC_ConfigConstants.EC_AUTOREPLY_LEN + 1)]
|
|
public string szAutoReply;
|
|
public float fCamTurnSpeed;
|
|
public float fCamZoomSpeed;
|
|
public byte nFontSize;
|
|
public bool bAtk_Player;
|
|
public bool bAtk_NoMafia;
|
|
public bool bAtk_NoWhite;
|
|
public bool bFontBold;
|
|
public bool bBls_NoRed;
|
|
public bool bBls_NoMafia;
|
|
public bool bBls_Self;
|
|
public bool bBlsRefuse_Neutral;
|
|
public bool bHideAutoGuide;
|
|
public bool bAtk_NoAlliance;
|
|
public bool bBls_NoAlliance;
|
|
public bool bBlsRefuse_NonTeammate;
|
|
public bool bAtk_NoForce;
|
|
public bool bBls_NoForce;
|
|
public bool bLockQuickBar;
|
|
public bool bPetAutoSkill;
|
|
public bool bAutoTeamForTask;
|
|
public bool bDisableAutoWikiHelp;
|
|
public bool bExclusiveAwardMode;
|
|
public bool bHideIceThunderBall;
|
|
|
|
public void Reset()
|
|
{
|
|
bNoTeamRequest = false;
|
|
bNoTradeRequest = false;
|
|
bTurnaround = false;
|
|
bReverseWheel = false;
|
|
bAutoReply = false;
|
|
szAutoReply = "";
|
|
fCamTurnSpeed = 10.0f;
|
|
fCamZoomSpeed = 1.0f;
|
|
nFontSize = 2;
|
|
bAtk_Player = false;
|
|
bAtk_NoMafia = true;
|
|
bAtk_NoWhite = false;
|
|
bBls_NoRed = false;
|
|
bBls_NoMafia = false;
|
|
bBls_Self = false;
|
|
bBlsRefuse_Neutral = false;
|
|
bFontBold = true;
|
|
bHideAutoGuide = false;
|
|
bAtk_NoAlliance = true;
|
|
bBls_NoAlliance = false;
|
|
bBlsRefuse_NonTeammate = false;
|
|
bAtk_NoForce = false;
|
|
bBls_NoForce = false;
|
|
bLockQuickBar = false;
|
|
bPetAutoSkill = false;
|
|
bAutoTeamForTask = true;
|
|
bDisableAutoWikiHelp = false;
|
|
bExclusiveAwardMode = true;
|
|
bHideIceThunderBall = false;
|
|
|
|
// Initialize channel array with default values
|
|
bChannel = new bool[EC_ConfigConstants.EC_USERCHANNEL_NUM * 15];
|
|
bool[,] a_bChannel = new bool[,]
|
|
{
|
|
{ true, true, true, true, true, false, false, true, true, true, false, true, true, true, true },
|
|
{ false, false, true, false, false, false, false, false, true, true, false, true, true, true, true },
|
|
{ false, false, false, true, false, false, false, false, true, true, false, true, true, true, true },
|
|
{ false, false, false, false, true, false, false, false, true, true, false, true, true, true, true },
|
|
{ false, false, false, false, false, false, false, true, true, true, false, true, true, true, true },
|
|
{ false, false, false, false, false, false, true, false, false, false, true, false, false, false, false }
|
|
};
|
|
|
|
for (int i = 0; i < EC_ConfigConstants.EC_USERCHANNEL_NUM; i++)
|
|
{
|
|
for (int j = 0; j < 15; j++)
|
|
{
|
|
bChannel[i * 15 + j] = a_bChannel[i, j];
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Read(BinaryReader reader, uint dwVer)
|
|
{
|
|
Reset();
|
|
|
|
if (dwVer < 15) return;
|
|
|
|
bNoTeamRequest = reader.ReadBoolean();
|
|
bNoTradeRequest = reader.ReadBoolean();
|
|
bTurnaround = reader.ReadBoolean();
|
|
bReverseWheel = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 29)
|
|
{
|
|
for (int i = 0; i < EC_ConfigConstants.EC_USERCHANNEL_NUM * 15; i++)
|
|
{
|
|
bChannel[i] = reader.ReadBoolean();
|
|
}
|
|
}
|
|
else if (dwVer >= 26)
|
|
{
|
|
for (int i = 0; i < EC_ConfigConstants.EC_USERCHANNEL_NUM * 14; i++)
|
|
{
|
|
if (i < bChannel.Length)
|
|
bChannel[i] = reader.ReadBoolean();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < EC_ConfigConstants.EC_USERCHANNEL_NUM * 13; i++)
|
|
{
|
|
if (i < bChannel.Length)
|
|
bChannel[i] = reader.ReadBoolean();
|
|
}
|
|
}
|
|
|
|
bAutoReply = reader.ReadBoolean();
|
|
szAutoReply = Encoding.UTF8.GetString(reader.ReadBytes(EC_ConfigConstants.EC_AUTOREPLY_LEN + 1)).TrimEnd('\0');
|
|
fCamTurnSpeed = reader.ReadSingle();
|
|
fCamZoomSpeed = reader.ReadSingle();
|
|
nFontSize = reader.ReadByte();
|
|
bAtk_Player = reader.ReadBoolean();
|
|
bAtk_NoMafia = reader.ReadBoolean();
|
|
bAtk_NoWhite = reader.ReadBoolean();
|
|
bFontBold = reader.ReadBoolean();
|
|
bBls_NoRed = reader.ReadBoolean();
|
|
bBls_NoMafia = reader.ReadBoolean();
|
|
bBls_Self = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 17)
|
|
bBlsRefuse_Neutral = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 18)
|
|
bHideAutoGuide = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 19)
|
|
bAtk_NoAlliance = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 20)
|
|
bBls_NoAlliance = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 23)
|
|
bBlsRefuse_NonTeammate = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 25)
|
|
{
|
|
bAtk_NoForce = reader.ReadBoolean();
|
|
bBls_NoForce = reader.ReadBoolean();
|
|
}
|
|
|
|
if (dwVer >= 32)
|
|
{
|
|
bLockQuickBar = reader.ReadBoolean();
|
|
bPetAutoSkill = reader.ReadBoolean();
|
|
}
|
|
|
|
if (dwVer >= 33)
|
|
bAutoTeamForTask = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 34)
|
|
bDisableAutoWikiHelp = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 35)
|
|
bExclusiveAwardMode = reader.ReadBoolean();
|
|
|
|
if (dwVer >= 36)
|
|
bHideIceThunderBall = reader.ReadBoolean();
|
|
}
|
|
}
|
|
|
|
// Blacklist Settings Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_BLACKLIST_SETTING
|
|
{
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = EC_ConfigConstants.EC_BLACKLIST_LEN)]
|
|
public int[] idPlayer;
|
|
public int levelBlock;
|
|
|
|
public void Reset()
|
|
{
|
|
idPlayer = new int[EC_ConfigConstants.EC_BLACKLIST_LEN];
|
|
levelBlock = 0;
|
|
}
|
|
|
|
public void Read(BinaryReader reader, uint dwVer)
|
|
{
|
|
Reset();
|
|
|
|
if (dwVer < 15) return;
|
|
|
|
for (int i = 0; i < EC_ConfigConstants.EC_BLACKLIST_LEN; i++)
|
|
{
|
|
idPlayer[i] = reader.ReadInt32();
|
|
}
|
|
|
|
if (dwVer >= 18)
|
|
levelBlock = reader.ReadInt32();
|
|
}
|
|
}
|
|
|
|
// Computer Aided Settings Structure
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct EC_COMPUTER_AIDED_SETTING
|
|
{
|
|
public const int GROUP_COUNT = 5;
|
|
|
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
|
public struct ITEM_GROUP
|
|
{
|
|
public bool enable;
|
|
public int item;
|
|
public sbyte percent;
|
|
public short slot;
|
|
|
|
public void Reset()
|
|
{
|
|
enable = false;
|
|
item = 0;
|
|
percent = 0;
|
|
slot = -1;
|
|
}
|
|
}
|
|
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = GROUP_COUNT)]
|
|
public ITEM_GROUP[] group;
|
|
|
|
public void Reset()
|
|
{
|
|
group = new ITEM_GROUP[GROUP_COUNT];
|
|
for (int i = 0; i < GROUP_COUNT; ++i)
|
|
{
|
|
group[i].Reset();
|
|
}
|
|
}
|
|
|
|
public void DisableAll()
|
|
{
|
|
for (int i = 0; i < GROUP_COUNT; ++i)
|
|
{
|
|
group[i].enable = false;
|
|
}
|
|
}
|
|
|
|
public void Read(BinaryReader reader, uint dwVer)
|
|
{
|
|
Reset();
|
|
|
|
if (dwVer < 27) return;
|
|
|
|
if (dwVer < 30)
|
|
{
|
|
ITEM_GROUP[] temp = new ITEM_GROUP[4];
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
temp[i].enable = reader.ReadBoolean();
|
|
temp[i].item = reader.ReadInt32();
|
|
temp[i].percent = reader.ReadSByte();
|
|
temp[i].slot = reader.ReadInt16();
|
|
}
|
|
Array.Copy(temp, group, 4);
|
|
}
|
|
else
|
|
{
|
|
for (int i = 0; i < GROUP_COUNT; i++)
|
|
{
|
|
group[i].enable = reader.ReadBoolean();
|
|
group[i].item = reader.ReadInt32();
|
|
group[i].percent = reader.ReadSByte();
|
|
group[i].slot = reader.ReadInt16();
|
|
}
|
|
}
|
|
|
|
DisableAll();
|
|
}
|
|
}
|
|
|
|
// Simple INI File Reader/Writer
|
|
public class SimpleIniFile
|
|
{
|
|
private Dictionary<string, Dictionary<string, string>> _sections = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
public bool Open(string filePath)
|
|
{
|
|
try
|
|
{
|
|
if (!File.Exists(filePath))
|
|
return false;
|
|
|
|
_sections.Clear();
|
|
string currentSection = "";
|
|
|
|
foreach (string line in File.ReadAllLines(filePath))
|
|
{
|
|
string trimmed = line.Trim();
|
|
if (string.IsNullOrEmpty(trimmed) || trimmed.StartsWith(";") || trimmed.StartsWith("#"))
|
|
continue;
|
|
|
|
if (trimmed.StartsWith("[") && trimmed.EndsWith("]"))
|
|
{
|
|
currentSection = trimmed.Substring(1, trimmed.Length - 2);
|
|
if (!_sections.ContainsKey(currentSection))
|
|
_sections[currentSection] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
else if (trimmed.Contains("="))
|
|
{
|
|
int eqIndex = trimmed.IndexOf('=');
|
|
string key = trimmed.Substring(0, eqIndex).Trim();
|
|
string value = trimmed.Substring(eqIndex + 1).Trim();
|
|
if (!_sections.ContainsKey(currentSection))
|
|
_sections[currentSection] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
_sections[currentSection][key] = value;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public string GetValueAsString(string section, string key, string defaultValue = "")
|
|
{
|
|
if (_sections.ContainsKey(section) && _sections[section].ContainsKey(key))
|
|
return _sections[section][key];
|
|
return defaultValue;
|
|
}
|
|
|
|
public int GetValueAsInt(string section, string key, int defaultValue = 0)
|
|
{
|
|
string value = GetValueAsString(section, key);
|
|
if (int.TryParse(value, out int result))
|
|
return result;
|
|
return defaultValue;
|
|
}
|
|
|
|
public float GetValueAsFloat(string section, string key, float defaultValue = 0.0f)
|
|
{
|
|
string value = GetValueAsString(section, key);
|
|
if (float.TryParse(value, out float result))
|
|
return result;
|
|
return defaultValue;
|
|
}
|
|
|
|
public bool GetValueAsBoolean(string section, string key, bool defaultValue = false)
|
|
{
|
|
string value = GetValueAsString(section, key);
|
|
if (bool.TryParse(value, out bool result))
|
|
return result;
|
|
int intValue = GetValueAsInt(section, key, defaultValue ? 1 : 0);
|
|
return intValue != 0;
|
|
}
|
|
|
|
public void GetValueAsIntArray(string section, string key, int count, int[] output)
|
|
{
|
|
string value = GetValueAsString(section, key);
|
|
string[] parts = value.Split(',');
|
|
for (int i = 0; i < count && i < parts.Length; i++)
|
|
{
|
|
if (int.TryParse(parts[i].Trim(), out int result))
|
|
output[i] = result;
|
|
}
|
|
}
|
|
|
|
public void GetValueAsFloatArray(string section, string key, int count, float[] output)
|
|
{
|
|
string value = GetValueAsString(section, key);
|
|
string[] parts = value.Split(',');
|
|
for (int i = 0; i < count && i < parts.Length; i++)
|
|
{
|
|
if (float.TryParse(parts[i].Trim(), out float result))
|
|
output[i] = result;
|
|
}
|
|
}
|
|
|
|
public void WriteStringValue(string section, string key, string value)
|
|
{
|
|
if (!_sections.ContainsKey(section))
|
|
_sections[section] = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
_sections[section][key] = value;
|
|
}
|
|
|
|
public void WriteIntValue(string section, string key, int value)
|
|
{
|
|
WriteStringValue(section, key, value.ToString());
|
|
}
|
|
|
|
public void Save(string filePath)
|
|
{
|
|
try
|
|
{
|
|
string directory = Path.GetDirectoryName(filePath);
|
|
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
|
|
Directory.CreateDirectory(directory);
|
|
|
|
using (StreamWriter writer = new StreamWriter(filePath))
|
|
{
|
|
foreach (var section in _sections)
|
|
{
|
|
writer.WriteLine($"[{section.Key}]");
|
|
foreach (var kvp in section.Value)
|
|
{
|
|
writer.WriteLine($"{kvp.Key}={kvp.Value}");
|
|
}
|
|
writer.WriteLine();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogError($"Failed to save INI file: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
_sections.Clear();
|
|
}
|
|
}
|
|
|
|
// Main Configs Class
|
|
public class CECConfigs
|
|
{
|
|
// Default environment values
|
|
public float m_fDefFogStart;
|
|
public float m_fDefFogEnd;
|
|
public float m_fDefFogDensity;
|
|
public uint m_dwDefFogColor;
|
|
public string m_strDefSkyFile0;
|
|
public string m_strDefSkyFile1;
|
|
public string m_strDefSkyFile2;
|
|
public uint m_dwDefLightDiff;
|
|
public uint m_dwDefLightSpec;
|
|
public Vector3 m_vDefLightDir;
|
|
public uint m_dwDefAmbient;
|
|
|
|
// Test code, temporary parameters
|
|
public bool m_bShowForest = true;
|
|
public bool m_bShowGrassLand = true;
|
|
|
|
// Configs user cannot change
|
|
private int m_iCodePage = 936;
|
|
private float m_fSevActiveRad = 213.0f;
|
|
private float m_fSceLoadRadius = 500.0f;
|
|
private float m_fMinPVRadius = 5.0f;
|
|
private float m_fCurPVRadius;
|
|
private float m_fForestDetail = 1.0f;
|
|
private float m_fGrassLandDetail = 1.0f;
|
|
private float m_fTrnLODDist1 = 180.0f;
|
|
private float m_fTrnLODDist2 = 320.0f;
|
|
private uint m_dwPlayerText = 0;
|
|
private uint m_dwNPCText = 0;
|
|
private int m_iMaxNameLen = 9;
|
|
private int m_iMultiClient = 1;
|
|
private string m_strWindowsTitle = "Element Client";
|
|
private string m_strMiniDLTitle = "";
|
|
private int m_iClientID = -1;
|
|
private bool m_bRegisterUIScriptFunc = false;
|
|
private bool m_bEnableGT = false;
|
|
private bool m_bEnableArc = false;
|
|
private bool m_bEnableArcAsia = false;
|
|
private bool m_bMiniClient = false;
|
|
private bool m_bSendLogicCheckInfo = false;
|
|
private List<string> m_strThemeFiles = new List<string>();
|
|
|
|
// DEBUG only settings
|
|
private bool m_bConsole = false;
|
|
private int m_iRTDebug = 1;
|
|
private bool m_bShowNPCID = false;
|
|
private float m_fRunSpeed = 5.0f;
|
|
private float m_fWalkSpeed = 2.0f;
|
|
private bool m_bTestDist = false;
|
|
private bool m_bShowPos = false;
|
|
private bool m_bGameStat = false;
|
|
private bool m_bShowID = false;
|
|
private bool m_bSkipFrame = false;
|
|
private bool m_bModelUpt = true;
|
|
private bool m_bDebugFog = false;
|
|
private float m_fDebugFogStart = 10.0f;
|
|
private float m_fDebugFogEnd = 100.0f;
|
|
private float m_fDebugFogDensity = 0.5f;
|
|
private uint m_dwDebugFogColor = 0xFFFFFFFF;
|
|
|
|
private bool m_bAdjusting = false;
|
|
|
|
// User settings
|
|
private EC_SYSTEM_SETTING m_ss;
|
|
private EC_VIDEO_SETTING m_vs;
|
|
private EC_GAME_SETTING m_gs;
|
|
private EC_BLACKLIST_SETTING m_bs;
|
|
private EC_COMPUTER_AIDED_SETTING m_cas;
|
|
|
|
// Blocked name list by adding sequence
|
|
private List<int> m_BlockedArr = new List<int>();
|
|
|
|
public CECConfigs()
|
|
{
|
|
m_fCurPVRadius = m_fSevActiveRad;
|
|
m_gs = default;
|
|
DefaultUserSettings(ref m_ss, ref m_vs, ref m_gs, ref m_bs, ref m_cas);
|
|
m_gs.bAtk_NoWhite = true;
|
|
m_gs.bAtk_NoForce = true;
|
|
}
|
|
|
|
public bool Init(string szCfgFile, string szClientIDFile, string szSSFile)
|
|
{
|
|
if (!LoadConfigs(szCfgFile, szClientIDFile))
|
|
{
|
|
Debug.LogError("CECConfigs::Init, Failed to load configs");
|
|
return false;
|
|
}
|
|
|
|
if (!LoadSystemSettings(szSSFile))
|
|
{
|
|
Debug.LogError("CECConfigs::Init, Failed to load system settings");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void DefaultUserSettings(ref EC_SYSTEM_SETTING pss, ref EC_VIDEO_SETTING pvs, ref EC_GAME_SETTING pgs, ref EC_BLACKLIST_SETTING pbs, ref EC_COMPUTER_AIDED_SETTING pcas)
|
|
{
|
|
pss.Reset();
|
|
pvs.Reset();
|
|
pgs.Reset();
|
|
pbs.Reset();
|
|
pcas.Reset();
|
|
}
|
|
|
|
private bool LoadConfigs(string szFile, string szClientIDFile)
|
|
{
|
|
SimpleIniFile iniFile = new SimpleIniFile();
|
|
|
|
if (!iniFile.Open(szFile))
|
|
{
|
|
Debug.LogWarning($"CECConfigs::LoadConfigs, Failed to open file {szFile}");
|
|
return false;
|
|
}
|
|
|
|
// PathFile section
|
|
string strSect = "PathFile";
|
|
|
|
m_strThemeFiles.Clear();
|
|
string strValue = iniFile.GetValueAsString(strSect, "theme");
|
|
if (!string.IsNullOrEmpty(strValue))
|
|
{
|
|
string[] themes = strValue.Split(',');
|
|
foreach (string theme in themes)
|
|
{
|
|
string trimmed = theme.Trim();
|
|
if (!string.IsNullOrEmpty(trimmed))
|
|
m_strThemeFiles.Add(trimmed);
|
|
}
|
|
}
|
|
|
|
// Settings section
|
|
strSect = "Settings";
|
|
|
|
m_iCodePage = iniFile.GetValueAsInt(strSect, "code_page", m_iCodePage);
|
|
m_bConsole = iniFile.GetValueAsInt(strSect, "console", m_bConsole ? 1 : 0) != 0;
|
|
m_iRTDebug = iniFile.GetValueAsInt(strSect, "runtime_debug", m_iRTDebug);
|
|
m_iMaxNameLen = iniFile.GetValueAsInt(strSect, "max_name_len", m_iMaxNameLen);
|
|
m_iMultiClient = iniFile.GetValueAsInt(strSect, "multi_client", m_iMultiClient);
|
|
m_strWindowsTitle = iniFile.GetValueAsString(strSect, "windows_title", m_strWindowsTitle);
|
|
m_strMiniDLTitle = iniFile.GetValueAsString(strSect, "mini_dl_title", m_strMiniDLTitle);
|
|
m_iClientID = iniFile.GetValueAsInt(strSect, "client_id", m_iClientID);
|
|
m_bRegisterUIScriptFunc = iniFile.GetValueAsInt(strSect, "register_script", m_bRegisterUIScriptFunc ? 1 : 0) != 0;
|
|
m_bEnableGT = iniFile.GetValueAsInt(strSect, "enable_gt", m_bEnableGT ? 1 : 0) != 0;
|
|
m_bEnableArc = iniFile.GetValueAsInt(strSect, "enable_coreclient", m_bEnableArc ? 1 : 0) != 0;
|
|
m_bEnableArcAsia = iniFile.GetValueAsInt(strSect, "enable_arcasia", m_bEnableArcAsia ? 1 : 0) != 0;
|
|
m_bMiniClient = iniFile.GetValueAsInt(strSect, "mini_client", m_bMiniClient ? 1 : 0) != 0;
|
|
m_bSendLogicCheckInfo = iniFile.GetValueAsInt(strSect, "logiccheck_info", m_bSendLogicCheckInfo ? 1 : 0) != 0;
|
|
|
|
// Default environment value
|
|
strSect = "DefEnv";
|
|
|
|
m_fDefFogStart = iniFile.GetValueAsFloat(strSect, "fog_start", 250.0f);
|
|
m_fDefFogEnd = iniFile.GetValueAsFloat(strSect, "fog_end", 600.0f);
|
|
m_fDefFogDensity = iniFile.GetValueAsFloat(strSect, "fog_density", 1.0f);
|
|
m_strDefSkyFile0 = iniFile.GetValueAsString(strSect, "sky_image01", "5\\Roof.bmp");
|
|
m_strDefSkyFile1 = iniFile.GetValueAsString(strSect, "sky_image02", "5\\01.bmp");
|
|
m_strDefSkyFile2 = iniFile.GetValueAsString(strSect, "sky_image03", "5\\02.bmp");
|
|
|
|
int[] col = new int[3];
|
|
iniFile.GetValueAsIntArray(strSect, "fog_color", 3, col);
|
|
m_dwDefFogColor = (uint)((col[0] << 16) | (col[1] << 8) | col[2]);
|
|
|
|
iniFile.GetValueAsIntArray(strSect, "ambient", 3, col);
|
|
m_dwDefAmbient = (uint)((col[0] << 16) | (col[1] << 8) | col[2]);
|
|
|
|
iniFile.GetValueAsIntArray(strSect, "light_diffuse", 3, col);
|
|
m_dwDefLightDiff = (uint)((col[0] << 16) | (col[1] << 8) | col[2]);
|
|
|
|
iniFile.GetValueAsIntArray(strSect, "light_specular", 3, col);
|
|
m_dwDefLightSpec = (uint)((col[0] << 16) | (col[1] << 8) | col[2]);
|
|
|
|
float[] lightDir = new float[3];
|
|
iniFile.GetValueAsFloatArray(strSect, "light_dir", 3, lightDir);
|
|
m_vDefLightDir = new Vector3(lightDir[0], lightDir[1], lightDir[2]);
|
|
m_vDefLightDir.Normalize();
|
|
|
|
iniFile.Close();
|
|
|
|
if (File.Exists(szClientIDFile))
|
|
{
|
|
SimpleIniFile clientIDFile = new SimpleIniFile();
|
|
if (clientIDFile.Open(szClientIDFile))
|
|
{
|
|
m_iClientID = clientIDFile.GetValueAsInt("Default", "client_id", m_iClientID);
|
|
clientIDFile.Close();
|
|
}
|
|
}
|
|
|
|
if (m_iClientID != -1)
|
|
{
|
|
Debug.Log($"client_id = {m_iClientID}");
|
|
}
|
|
|
|
m_bDebugFog = false;
|
|
m_fDebugFogStart = m_fDefFogStart;
|
|
m_fDebugFogEnd = m_fDefFogEnd;
|
|
m_fDebugFogDensity = m_fDefFogDensity;
|
|
m_dwDebugFogColor = m_dwDefFogColor;
|
|
|
|
return true;
|
|
}
|
|
|
|
private bool LoadSystemSettings(string szFile)
|
|
{
|
|
SimpleIniFile iniFile = new SimpleIniFile();
|
|
|
|
if (!iniFile.Open(szFile))
|
|
{
|
|
Debug.LogWarning($"CECConfigs::LoadSystemSettings, Failed to open file {szFile}");
|
|
Debug.LogWarning("we use default settings to let users go in...");
|
|
return true;
|
|
}
|
|
|
|
// Video section
|
|
string strSect = "Video";
|
|
|
|
m_ss.nLevel = (byte)iniFile.GetValueAsInt(strSect, "Level", 0);
|
|
m_ss.nSight = (byte)iniFile.GetValueAsInt(strSect, "Sight", 0);
|
|
m_ss.nWaterEffect = (byte)iniFile.GetValueAsInt(strSect, "WaterEffect", 0);
|
|
m_ss.bSimpleTerrain = iniFile.GetValueAsInt(strSect, "SimpleTerrain", 0) != 0;
|
|
m_ss.nTreeDetail = (byte)iniFile.GetValueAsInt(strSect, "TreeDetail", 0);
|
|
m_ss.nGrassDetail = (byte)iniFile.GetValueAsInt(strSect, "GrassDetail", 0);
|
|
m_ss.nCloudDetail = (byte)iniFile.GetValueAsInt(strSect, "CloudDetail", 0);
|
|
m_ss.bShadow = iniFile.GetValueAsInt(strSect, "Shadow", 0) != 0;
|
|
m_ss.bMipMapBias = iniFile.GetValueAsInt(strSect, "MipMapBias", 0) != 0;
|
|
m_ss.bFullGlow = iniFile.GetValueAsInt(strSect, "FullGlow", 0) != 0;
|
|
m_ss.bSpaceWarp = iniFile.GetValueAsInt(strSect, "SpaceWarp", 0) != 0;
|
|
m_ss.bSunFlare = iniFile.GetValueAsInt(strSect, "SunFlare", 0) != 0;
|
|
m_ss.bAdvancedWater = iniFile.GetValueAsInt(strSect, "AdvancedWaterUD", 0) != 0;
|
|
|
|
m_ss.iRndWidth = iniFile.GetValueAsInt(strSect, "RenderWid", 800);
|
|
m_ss.iRndHeight = iniFile.GetValueAsInt(strSect, "RenderHei", 600);
|
|
m_ss.iTexDetail = iniFile.GetValueAsInt(strSect, "TexDetail", 2);
|
|
m_ss.iSoundQuality = iniFile.GetValueAsInt(strSect, "SoundQuality", 2);
|
|
m_ss.bFullScreen = iniFile.GetValueAsInt(strSect, "FullScreen", 1) != 0;
|
|
m_ss.bWideScreen = iniFile.GetValueAsInt(strSect, "WideScreen", 0) != 0;
|
|
m_ss.bScaleUI = iniFile.GetValueAsInt(strSect, "ScaleUI", 0) != 0;
|
|
m_ss.bVSync = iniFile.GetValueAsInt(strSect, "VerticalSync", 1) != 0;
|
|
m_ss.iGamma = iniFile.GetValueAsInt(strSect, "Gamma", 41);
|
|
|
|
// Audio section
|
|
strSect = "Audio";
|
|
|
|
m_ss.nSoundVol = (byte)iniFile.GetValueAsInt(strSect, "SoundVol", 50);
|
|
m_ss.nMusicVol = (byte)iniFile.GetValueAsInt(strSect, "MusicVol", 50);
|
|
|
|
// UI section
|
|
m_ss.iTheme = EC_ConfigConstants.DEFAULT_UI_THEME_ID;
|
|
|
|
// Optimize section
|
|
strSect = "Optimize";
|
|
// Note: CECOptimize class would need to be implemented separately
|
|
// m_ops.gfx.bExcludeHost = iniFile.GetValueAsBoolean(strSect, "ExcludeHost", false);
|
|
// ... other optimize settings
|
|
|
|
iniFile.Close();
|
|
|
|
ConvertSightSetting(m_ss.nSight);
|
|
|
|
m_fForestDetail = m_ss.nTreeDetail * 0.2f;
|
|
m_fGrassLandDetail = m_ss.nGrassDetail * 0.25f;
|
|
|
|
return true;
|
|
}
|
|
|
|
public float GetSceneLoadRadius()
|
|
{
|
|
// Note: Would need EC_Game reference to check game state
|
|
return m_fSceLoadRadius;
|
|
}
|
|
|
|
public void SetPlayerVisRadius(float fRadius)
|
|
{
|
|
m_fCurPVRadius = fRadius;
|
|
m_fCurPVRadius = Mathf.Clamp(m_fCurPVRadius, m_fMinPVRadius, m_fSevActiveRad);
|
|
}
|
|
|
|
public bool SaveSystemSettings()
|
|
{
|
|
SimpleIniFile iniFile = new SimpleIniFile();
|
|
|
|
// Info section
|
|
string strSect = "Info";
|
|
// Note: Graphics card info would need Unity/System integration
|
|
iniFile.WriteStringValue(strSect, "card", "Unknown");
|
|
iniFile.WriteStringValue(strSect, "driver", "Unknown");
|
|
iniFile.WriteStringValue(strSect, "version", "1.0.0.0");
|
|
iniFile.WriteStringValue(strSect, "vendor", "00000000");
|
|
iniFile.WriteStringValue(strSect, "deviceid", "00000000");
|
|
iniFile.WriteStringValue(strSect, "subsysid", "00000000");
|
|
iniFile.WriteStringValue(strSect, "guid", "{00000000-0000-0000-0000-000000000000}");
|
|
|
|
// Video section
|
|
strSect = "Video";
|
|
|
|
iniFile.WriteIntValue(strSect, "Level", m_ss.nLevel);
|
|
iniFile.WriteIntValue(strSect, "Sight", m_ss.nSight);
|
|
iniFile.WriteIntValue(strSect, "WaterEffect", m_ss.nWaterEffect);
|
|
iniFile.WriteIntValue(strSect, "SimpleTerrain", m_ss.bSimpleTerrain ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "TreeDetail", m_ss.nTreeDetail);
|
|
iniFile.WriteIntValue(strSect, "GrassDetail", m_ss.nGrassDetail);
|
|
iniFile.WriteIntValue(strSect, "CloudDetail", m_ss.nCloudDetail);
|
|
iniFile.WriteIntValue(strSect, "Shadow", m_ss.bShadow ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "MipMapBias", m_ss.bMipMapBias ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "FullGlow", m_ss.bFullGlow ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "SpaceWarp", m_ss.bSpaceWarp ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "SunFlare", m_ss.bSunFlare ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "AdvancedWaterUD", m_ss.bAdvancedWater ? 1 : 0);
|
|
|
|
iniFile.WriteIntValue(strSect, "RenderWid", m_ss.iRndWidth);
|
|
iniFile.WriteIntValue(strSect, "RenderHei", m_ss.iRndHeight);
|
|
iniFile.WriteIntValue(strSect, "TexDetail", m_ss.iTexDetail);
|
|
iniFile.WriteIntValue(strSect, "SoundQuality", m_ss.iSoundQuality);
|
|
iniFile.WriteIntValue(strSect, "FullScreen", m_ss.bFullScreen ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "WideScreen", m_ss.bWideScreen ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "ScaleUI", m_ss.bScaleUI ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "VerticalSync", m_ss.bVSync ? 1 : 0);
|
|
iniFile.WriteIntValue(strSect, "Gamma", m_ss.iGamma);
|
|
|
|
// Audio section
|
|
strSect = "Audio";
|
|
|
|
iniFile.WriteIntValue(strSect, "SoundVol", m_ss.nSoundVol);
|
|
iniFile.WriteIntValue(strSect, "MusicVol", m_ss.nMusicVol);
|
|
|
|
// UI section
|
|
strSect = "UI";
|
|
iniFile.WriteIntValue(strSect, "Theme", m_ss.iTheme);
|
|
|
|
// Optimize section
|
|
strSect = "Optimize";
|
|
// Note: Would need CECOptimize implementation
|
|
// iniFile.WriteIntValue(strSect, "ExcludeHost", m_ops.gfx.bExcludeHost ? 1 : 0);
|
|
// ... other optimize settings
|
|
|
|
string filePath = Path.Combine(Application.persistentDataPath, "userdata", "SystemSettings.ini");
|
|
iniFile.Save(filePath);
|
|
iniFile.Close();
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool SaveUserConfigData(byte[] pDataBuf, out int piSize)
|
|
{
|
|
piSize = 0;
|
|
int iTotalSize = 0;
|
|
|
|
iTotalSize += sizeof(uint); // Version
|
|
iTotalSize += Marshal.SizeOf(typeof(EC_VIDEO_SETTING));
|
|
iTotalSize += Marshal.SizeOf(typeof(EC_GAME_SETTING));
|
|
iTotalSize += Marshal.SizeOf(typeof(EC_BLACKLIST_SETTING));
|
|
iTotalSize += Marshal.SizeOf(typeof(EC_COMPUTER_AIDED_SETTING));
|
|
|
|
if (pDataBuf != null && pDataBuf.Length >= iTotalSize)
|
|
{
|
|
using (MemoryStream ms = new MemoryStream(pDataBuf))
|
|
using (BinaryWriter writer = new BinaryWriter(ms))
|
|
{
|
|
writer.Write((uint)EC_ConfigConstants.EC_CONFIG_VERSION);
|
|
// Note: Would need proper serialization for structs
|
|
// This is a simplified version
|
|
}
|
|
}
|
|
|
|
piSize = iTotalSize;
|
|
return true;
|
|
}
|
|
|
|
public void DefaultUserConfigData()
|
|
{
|
|
DefaultUserSettings(ref m_ss, ref m_vs, ref m_gs, ref m_bs, ref m_cas);
|
|
|
|
// This fix a bug in some version
|
|
m_gs.fCamTurnSpeed = 10.0f;
|
|
m_gs.fCamZoomSpeed = 1.0f;
|
|
}
|
|
|
|
public bool LoadUserConfigData(byte[] pDataBuf, int iDataSize)
|
|
{
|
|
try
|
|
{
|
|
using (MemoryStream ms = new MemoryStream(pDataBuf, 0, iDataSize))
|
|
using (BinaryReader reader = new BinaryReader(ms))
|
|
{
|
|
uint dwVer = reader.ReadUInt32();
|
|
|
|
if (dwVer < 15)
|
|
{
|
|
DefaultUserConfigData();
|
|
return true;
|
|
}
|
|
else if (dwVer > EC_ConfigConstants.EC_CONFIG_VERSION)
|
|
{
|
|
Debug.LogError("CECConfigs::LoadUserConfigData, version mismatch");
|
|
DefaultUserConfigData();
|
|
return false;
|
|
}
|
|
|
|
m_vs.Read(reader, dwVer);
|
|
m_gs.Read(reader, dwVer);
|
|
m_bs.Read(reader, dwVer);
|
|
m_cas.Read(reader, dwVer);
|
|
}
|
|
|
|
ApplyUserSetting();
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"CECConfigs::LoadUserConfigData, data read error: {e.Message}");
|
|
DefaultUserConfigData();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void ApplyUserSetting()
|
|
{
|
|
Verify();
|
|
|
|
BuildTextFlags();
|
|
|
|
m_fCurPVRadius = CalcPlayerVisRadius(m_vs.nDistance);
|
|
// Note: Would need EC_Game reference
|
|
// g_pGame->GetA3DGFXExMan()->SetPriority(m_vs.nEffect);
|
|
}
|
|
|
|
public void SetSceneLoadRadius(float fRadius)
|
|
{
|
|
m_fSceLoadRadius = fRadius;
|
|
m_fSceLoadRadius = Mathf.Max(m_fSceLoadRadius, m_fSevActiveRad);
|
|
// Note: Would need EC_Game reference
|
|
// g_pGame->GetGameRun()->GetWorld()->SetViewRadius(fRadius);
|
|
}
|
|
|
|
public void SetForestDetail(float fDetail)
|
|
{
|
|
m_fForestDetail = fDetail;
|
|
m_fForestDetail = Mathf.Clamp(m_fForestDetail, 0.0f, 1.0f);
|
|
// Note: Would need EC_Game reference
|
|
// g_pGame->GetGameRun()->GetWorld()->GetForest()->SetLODLevel(m_fForestDetail);
|
|
}
|
|
|
|
public void SetGrassLandDetail(float fDetail)
|
|
{
|
|
m_fGrassLandDetail = fDetail;
|
|
m_fGrassLandDetail = Mathf.Clamp(m_fGrassLandDetail, 0.0f, 1.0f);
|
|
// Note: Would need EC_Game reference
|
|
// g_pGame->GetGameRun()->GetWorld()->GetGrassLand()->SetLODLevel(m_fGrassLandDetail);
|
|
}
|
|
|
|
public void SetSystemSettings(EC_SYSTEM_SETTING systemSetting, bool bCallFromWndProc = false)
|
|
{
|
|
// Note: This is a simplified version - full implementation would need EC_Game references
|
|
EC_SYSTEM_SETTING ss = systemSetting;
|
|
ApplyWorldSpecificSetting(ref ss);
|
|
ss.iTheme = EC_ConfigConstants.DEFAULT_UI_THEME_ID;
|
|
|
|
// Apply settings...
|
|
m_ss = ss;
|
|
}
|
|
|
|
public void SetVideoSettings(EC_VIDEO_SETTING vs)
|
|
{
|
|
m_vs = vs;
|
|
|
|
BuildTextFlags();
|
|
|
|
m_fCurPVRadius = CalcPlayerVisRadius(m_vs.nDistance);
|
|
|
|
// Note: Would need EC_Game reference
|
|
// g_pGame->GetA3DGFXExMan()->SetPriority(m_vs.nEffect);
|
|
}
|
|
|
|
public void SetGameSettings(EC_GAME_SETTING gs)
|
|
{
|
|
m_gs = gs;
|
|
}
|
|
|
|
public void SetBlackListSettings(EC_BLACKLIST_SETTING bs)
|
|
{
|
|
m_bs = bs;
|
|
}
|
|
|
|
public void SetComputerAidedSetting(EC_COMPUTER_AIDED_SETTING cas)
|
|
{
|
|
m_cas = cas;
|
|
}
|
|
|
|
private void ConvertSightSetting(int iSight)
|
|
{
|
|
switch (iSight)
|
|
{
|
|
case 0:
|
|
m_fSceLoadRadius = m_fSevActiveRad;
|
|
m_fTrnLODDist1 = 40.0f;
|
|
m_fTrnLODDist2 = 80.0f;
|
|
break;
|
|
|
|
case 1:
|
|
m_fSceLoadRadius = 250.0f;
|
|
m_fTrnLODDist1 = 120.0f;
|
|
m_fTrnLODDist2 = 240.0f;
|
|
break;
|
|
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
m_fSceLoadRadius = 420.0f;
|
|
m_fTrnLODDist1 = 180.0f;
|
|
m_fTrnLODDist2 = 320.0f;
|
|
break;
|
|
|
|
default:
|
|
Debug.LogError($"CECConfigs::ConvertSightSetting, invalid sight setting: {iSight}");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void BuildTextFlags()
|
|
{
|
|
m_dwPlayerText = 0;
|
|
|
|
if (m_vs.bPlayerHeadText)
|
|
{
|
|
// Note: Would need CECPlayer constants
|
|
// m_dwPlayerText |= m_vs.bPlayerName ? CECPlayer::RNF_NAME : 0;
|
|
// m_dwPlayerText |= m_vs.bPlayerTitle ? CECPlayer::RNF_TITLE : 0;
|
|
// etc.
|
|
}
|
|
|
|
if (m_vs.bPlayerShop)
|
|
{
|
|
// Note: Would need CECPlayer constants
|
|
// m_dwPlayerText |= m_vs.bPlayerShop ? CECPlayer::RNF_BUY : 0;
|
|
// m_dwPlayerText |= m_vs.bPlayerShop ? CECPlayer::RNF_SELL : 0;
|
|
}
|
|
|
|
m_dwNPCText = 0;
|
|
// Note: Would need CECNPC constants
|
|
// m_dwNPCText |= m_vs.bNPCName ? CECNPC::RNF_NPCNAME : 0;
|
|
// m_dwNPCText |= m_vs.bMonsterName ? CECNPC::RNF_MONSTERNAME : 0;
|
|
// m_dwNPCText |= CECNPC::RNF_WORDS;
|
|
}
|
|
|
|
private void Verify()
|
|
{
|
|
// Verify game setting
|
|
if (m_gs.szAutoReply != null && m_gs.szAutoReply.Length > EC_ConfigConstants.EC_AUTOREPLY_LEN)
|
|
{
|
|
m_gs.szAutoReply = m_gs.szAutoReply.Substring(0, EC_ConfigConstants.EC_AUTOREPLY_LEN);
|
|
}
|
|
|
|
if (m_gs.nFontSize > 4)
|
|
{
|
|
Debug.LogWarning($"CECConfigs::Verify, found invalid nFontSize == {m_gs.nFontSize}");
|
|
m_gs.nFontSize = 4;
|
|
}
|
|
|
|
if (m_gs.fCamTurnSpeed != 10.0f)
|
|
{
|
|
Debug.LogWarning($"CECConfigs::Verify, found invalid fCamTurnSpeed == {m_gs.fCamTurnSpeed}");
|
|
m_gs.fCamTurnSpeed = 10.0f;
|
|
}
|
|
|
|
if (m_gs.fCamZoomSpeed != 1.0f)
|
|
{
|
|
Debug.LogWarning($"CECConfigs::Verify, found invalid fCamZoomSpeed == {m_gs.fCamZoomSpeed}");
|
|
m_gs.fCamZoomSpeed = 1.0f;
|
|
}
|
|
|
|
if (m_vs.nDistance > 100)
|
|
{
|
|
Debug.LogWarning($"CECConfigs::Verify, found invalid nDistance == {m_vs.nDistance}");
|
|
m_vs.nDistance = 100;
|
|
}
|
|
|
|
if (m_vs.nEffect > 4)
|
|
{
|
|
Debug.LogWarning($"CECConfigs::Verify, found invalid nEffect == {m_vs.nEffect}");
|
|
m_vs.nEffect = 4;
|
|
}
|
|
|
|
// Note: Would need CECHostPlayer constants for tab selection type verification
|
|
// VerifyComboSkills();
|
|
}
|
|
|
|
public float CalcPlayerVisRadius(int iPercent)
|
|
{
|
|
return m_fMinPVRadius + (m_fSevActiveRad - m_fMinPVRadius) * iPercent / 100.0f;
|
|
}
|
|
|
|
public string GetRandomThemeFile()
|
|
{
|
|
if (m_strThemeFiles.Count > 0)
|
|
{
|
|
int index = UnityEngine.Random.Range(0, m_strThemeFiles.Count);
|
|
return "music\\" + m_strThemeFiles[index];
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public bool IsPlayerBlocked(int idPlayer)
|
|
{
|
|
return m_BlockedArr.Contains(idPlayer);
|
|
}
|
|
|
|
public void SetBlockedName(int idPlayer, string pName)
|
|
{
|
|
if (idPlayer <= 0)
|
|
return;
|
|
|
|
bool bBlocked = IsPlayerBlocked(idPlayer);
|
|
if (string.IsNullOrEmpty(pName))
|
|
{
|
|
if (bBlocked)
|
|
{
|
|
m_BlockedArr.Remove(idPlayer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!bBlocked)
|
|
{
|
|
m_BlockedArr.Add(idPlayer);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int LoadBlockedList()
|
|
{
|
|
m_BlockedArr.Clear();
|
|
|
|
for (int i = 0; i < EC_ConfigConstants.EC_BLACKLIST_LEN; i++)
|
|
{
|
|
int id = m_bs.idPlayer[i];
|
|
if (id <= 0) break;
|
|
m_BlockedArr.Add(id);
|
|
}
|
|
|
|
// Note: Would need to load from file
|
|
// string strFile = Path.Combine(Application.persistentDataPath, "userdata", "blacklist", $"{characterID}.dat");
|
|
// Load from file if exists
|
|
|
|
return m_BlockedArr.Count;
|
|
}
|
|
|
|
public void SaveBlockedID()
|
|
{
|
|
// Note: Would need character ID
|
|
// string strDir = Path.Combine(Application.persistentDataPath, "userdata", "blacklist");
|
|
// Directory.CreateDirectory(strDir);
|
|
// string strFile = Path.Combine(strDir, $"{characterID}.dat");
|
|
// Save to file
|
|
}
|
|
|
|
public void ApplyWorldSpecificSetting()
|
|
{
|
|
if (m_bAdjusting)
|
|
return;
|
|
|
|
m_bAdjusting = true;
|
|
// Note: Would need EC_Game references for water effects
|
|
// if (!IsUseWaterRefract() && CanUseWaterRefract() && ShouldForceWaterRefract())
|
|
// UseWaterRefract();
|
|
// if (!IsUseWaterReflect() && CanUseWaterReflect() && ShouldForceWaterReflect())
|
|
// UseWaterReflect();
|
|
m_bAdjusting = false;
|
|
}
|
|
|
|
private void ApplyWorldSpecificSetting(ref EC_SYSTEM_SETTING ss)
|
|
{
|
|
// Note: Would need EC_Game references
|
|
// if (!IsUseWaterRefract(ss) && CanUseWaterRefract() && ShouldForceWaterRefract())
|
|
// UseWaterRefract(ss);
|
|
// if (!IsUseWaterReflect(ss) && CanUseWaterReflect() && ShouldForceWaterReflect())
|
|
// UseWaterReflect(ss);
|
|
}
|
|
|
|
// Getters
|
|
public int GetLanCodePage() { return m_iCodePage; }
|
|
public float GetDefFogStart() { return m_fDefFogStart; }
|
|
public float GetDefFogEnd() { return m_fDefFogEnd; }
|
|
public float GetDefFogDensity() { return m_fDefFogDensity; }
|
|
public uint GetDefFogColor() { return m_dwDefFogColor; }
|
|
public float GetSevActiveRadius() { return m_fSevActiveRad; }
|
|
public float GetPlayerVisRadius() { return m_fCurPVRadius; }
|
|
public float GetForestDetail() { return m_fForestDetail; }
|
|
public float GetGrassLandDetail() { return m_fGrassLandDetail; }
|
|
public float GetTerrainLODDist1() { return m_fTrnLODDist1; }
|
|
public float GetTerrainLODDist2() { return m_fTrnLODDist2; }
|
|
public uint GetPlayerTextFlags() { return m_dwPlayerText; }
|
|
public uint GetNPCTextFlags() { return m_dwNPCText; }
|
|
public int GetMaxNameLen() { return m_iMaxNameLen; }
|
|
public int GetMultiClient() { return m_iMultiClient; }
|
|
public string GetWindowsTitle() { return m_strWindowsTitle; }
|
|
public string GetMiniDLTitle() { return m_strMiniDLTitle; }
|
|
public int GetClientID() { return m_iClientID; }
|
|
public bool GetRegisterScriptFunc() { return m_bRegisterUIScriptFunc; }
|
|
public bool GetEnableGT() { return m_bEnableGT; }
|
|
public bool GetEnableArc() { return m_bEnableArc; }
|
|
public bool GetEnableArcAsia() { return m_bEnableArcAsia; }
|
|
public bool IsMiniClient() { return m_bMiniClient; }
|
|
public bool IsSendLogicCheckInfo() { return m_bSendLogicCheckInfo; }
|
|
public bool HasConsole() { return m_bConsole; }
|
|
public void EnableConsole(bool bEnable) { m_bConsole = bEnable; }
|
|
public void SetRTDebugLevel(int iLevel) { m_iRTDebug = iLevel; }
|
|
public int GetRTDebugLevel() { return m_iRTDebug; }
|
|
public void ShowNPCID(bool bShow) { m_bShowNPCID = bShow; }
|
|
public bool IsNPCIDShown() { return m_bShowNPCID; }
|
|
public void SetHostRunSpeed(float fSpeed)
|
|
{
|
|
if (fSpeed > 0.0f && fSpeed <= 15.0f)
|
|
m_fRunSpeed = fSpeed;
|
|
}
|
|
public float GetHostRunSpeed() { return m_fRunSpeed; }
|
|
public float GetHostWalkSpeed() { return m_fWalkSpeed; }
|
|
public bool GetTestDistFlag() { return m_bTestDist; }
|
|
public void SetTestDistFlag(bool bFlag) { m_bTestDist = bFlag; }
|
|
public bool GetShowPosFlag() { return m_bShowPos; }
|
|
public void SetShowPosFlag(bool bFlag) { m_bShowPos = bFlag; }
|
|
public bool GetShowForestFlag() { return m_bShowForest; }
|
|
public void SetShowForestFlag(bool bFlag) { m_bShowForest = bFlag; }
|
|
public bool GetShowGameStatFlag() { return m_bGameStat; }
|
|
public void SetShowGameStatFlag(bool bFlag) { m_bGameStat = bFlag; }
|
|
public bool GetShowIDFlag() { return m_bShowID; }
|
|
public void SetShowIDFlag(bool bFlag) { m_bShowID = bFlag; }
|
|
public bool GetSkipFrameFlag() { return m_bSkipFrame; }
|
|
public void SetSkipFrameFlag(bool bTrue) { m_bSkipFrame = bTrue; }
|
|
public bool GetModelUpdateFlag() { return m_bModelUpt; }
|
|
public void SetModelUpdateFlag(bool bTrue) { m_bModelUpt = bTrue; }
|
|
public void SetDebugFog(bool bDebug) { m_bDebugFog = bDebug; }
|
|
public bool IsDebugFog() { return m_bDebugFog; }
|
|
public void SetDebugFogParameter(float fFogStart, float fFogEnd, float fFogDensity, uint fogColor)
|
|
{
|
|
m_fDebugFogStart = fFogStart;
|
|
m_fDebugFogEnd = fFogEnd;
|
|
m_fDebugFogDensity = fFogDensity;
|
|
m_dwDebugFogColor = fogColor;
|
|
}
|
|
public float GetDebugFogStart() { return m_fDebugFogStart; }
|
|
public float GetDebugFogEnd() { return m_fDebugFogEnd; }
|
|
public float GetDebugFogDensity() { return m_fDebugFogDensity; }
|
|
public uint GetDebugFogColor() { return m_dwDebugFogColor; }
|
|
public bool IsAdjusting() { return m_bAdjusting; }
|
|
public EC_SYSTEM_SETTING GetSystemSettings() { return m_ss; }
|
|
public EC_VIDEO_SETTING GetVideoSettings() { return m_vs; }
|
|
public EC_GAME_SETTING GetGameSettings() { return m_gs; }
|
|
public EC_BLACKLIST_SETTING GetBlackListSettings() { return m_bs; }
|
|
public EC_COMPUTER_AIDED_SETTING GetComputerAidedSetting() { return m_cas; }
|
|
public List<int> GetBlockedList() { return m_BlockedArr; }
|
|
}
|
|
}
|
|
|