Fixed server failing to assign jobs to all clients on some modded servers: if the max amount of players per job had been reached on all the jobs the client has in their preferences, the client would not get a job at all (causing crashes later on when trying to access the client's job). Now the server assigns a random job if none of the preferred jobs are available.
+ Fix for exceptions in Client constructor if there are less than 3 job prefabs.
This commit is contained in:
@@ -111,7 +111,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
votes = new object[Enum.GetNames(typeof(VoteType)).Length];
|
||||||
|
|
||||||
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0, 3));
|
jobPreferences = new List<JobPrefab>(JobPrefab.List.GetRange(0, Math.Min(JobPrefab.List.Count, 3)));
|
||||||
|
|
||||||
entityEventLastSent = new Dictionary<UInt16, float>();
|
entityEventLastSent = new Dictionary<UInt16, float>();
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ namespace Barotrauma.Networking
|
|||||||
name = name.Substring(0, 20);
|
name = name.Substring(0, 20);
|
||||||
}
|
}
|
||||||
string rName = "";
|
string rName = "";
|
||||||
for (int i=0;i<name.Length;i++)
|
for (int i = 0; i < name.Length; i++)
|
||||||
{
|
{
|
||||||
if (name[i] < 32)
|
if (name[i] < 32)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1921,7 +1921,11 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
unassigned = new List<Client>(unassigned);
|
unassigned = new List<Client>(unassigned);
|
||||||
|
|
||||||
int[] assignedClientCount = new int[JobPrefab.List.Count];
|
Dictionary<JobPrefab, int> assignedClientCount = new Dictionary<JobPrefab, int>();
|
||||||
|
foreach (JobPrefab jp in JobPrefab.List)
|
||||||
|
{
|
||||||
|
assignedClientCount.Add(jp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int teamID = 0;
|
int teamID = 0;
|
||||||
if (unassigned.Count > 0) teamID = unassigned[0].TeamID;
|
if (unassigned.Count > 0) teamID = unassigned[0].TeamID;
|
||||||
@@ -1930,16 +1934,16 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
if (characterInfo != null)
|
if (characterInfo != null)
|
||||||
{
|
{
|
||||||
assignedClientCount[JobPrefab.List.FindIndex(jp => jp == GameMain.NetLobbyScreen.JobPreferences[0])] = 1;
|
assignedClientCount[GameMain.NetLobbyScreen.JobPreferences[0]] = 1;
|
||||||
}
|
}
|
||||||
else if (myCharacter != null && !myCharacter.IsDead)
|
else if (myCharacter != null && !myCharacter.IsDead)
|
||||||
{
|
{
|
||||||
assignedClientCount[JobPrefab.List.IndexOf(myCharacter.Info.Job.Prefab)] = 1;
|
assignedClientCount[myCharacter.Info.Job.Prefab] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (myCharacter != null && !myCharacter.IsDead && myCharacter.TeamID == teamID)
|
else if (myCharacter != null && !myCharacter.IsDead && myCharacter.TeamID == teamID)
|
||||||
{
|
{
|
||||||
assignedClientCount[JobPrefab.List.IndexOf(myCharacter.Info.Job.Prefab)]++;
|
assignedClientCount[myCharacter.Info.Job.Prefab]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//count the clients who already have characters with an assigned job
|
//count the clients who already have characters with an assigned job
|
||||||
@@ -1948,7 +1952,7 @@ namespace Barotrauma.Networking
|
|||||||
if (c.TeamID != teamID || unassigned.Contains(c)) continue;
|
if (c.TeamID != teamID || unassigned.Contains(c)) continue;
|
||||||
if (c.Character != null && !c.Character.IsDead)
|
if (c.Character != null && !c.Character.IsDead)
|
||||||
{
|
{
|
||||||
assignedClientCount[JobPrefab.List.IndexOf(c.Character.Info.Job.Prefab)]++;
|
assignedClientCount[c.Character.Info.Job.Prefab]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1965,39 +1969,56 @@ namespace Barotrauma.Networking
|
|||||||
while (unassignedJobsFound && unassigned.Count > 0)
|
while (unassignedJobsFound && unassigned.Count > 0)
|
||||||
{
|
{
|
||||||
unassignedJobsFound = false;
|
unassignedJobsFound = false;
|
||||||
for (int i = 0; i < JobPrefab.List.Count; i++)
|
|
||||||
|
foreach (JobPrefab jobPrefab in JobPrefab.List)
|
||||||
{
|
{
|
||||||
if (unassigned.Count == 0) break;
|
if (unassigned.Count == 0) break;
|
||||||
if (JobPrefab.List[i].MinNumber < 1 || assignedClientCount[i] >= JobPrefab.List[i].MinNumber) continue;
|
if (jobPrefab.MinNumber < 1 || assignedClientCount[jobPrefab] >= jobPrefab.MinNumber) continue;
|
||||||
|
|
||||||
//find the client that wants the job the most, or force it to random client if none of them want it
|
//find the client that wants the job the most, or force it to random client if none of them want it
|
||||||
Client assignedClient = FindClientWithJobPreference(unassigned, JobPrefab.List[i], true);
|
Client assignedClient = FindClientWithJobPreference(unassigned, jobPrefab, true);
|
||||||
|
|
||||||
assignedClient.assignedJob = JobPrefab.List[i];
|
assignedClient.assignedJob = jobPrefab;
|
||||||
|
assignedClientCount[jobPrefab]++;
|
||||||
assignedClientCount[i]++;
|
|
||||||
unassigned.Remove(assignedClient);
|
unassigned.Remove(assignedClient);
|
||||||
|
|
||||||
//the job still needs more crew members, set unassignedJobsFound to true to keep the while loop running
|
//the job still needs more crew members, set unassignedJobsFound to true to keep the while loop running
|
||||||
if (assignedClientCount[i] < JobPrefab.List[i].MinNumber) unassignedJobsFound = true;
|
if (assignedClientCount[jobPrefab] < jobPrefab.MinNumber) unassignedJobsFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find a suitable job for the rest of the players
|
//find a suitable job for the rest of the players
|
||||||
for (int i = unassigned.Count - 1; i >= 0; i--)
|
foreach (Client c in unassigned)
|
||||||
{
|
{
|
||||||
for (int preferenceIndex = 0; preferenceIndex < 3; preferenceIndex++)
|
foreach (JobPrefab preferredJob in c.jobPreferences)
|
||||||
{
|
{
|
||||||
int jobIndex = JobPrefab.List.FindIndex(jp => jp == unassigned[i].jobPreferences[preferenceIndex]);
|
//the maximum number of players that can have this job hasn't been reached yet
|
||||||
|
// -> assign it to the client
|
||||||
|
if (assignedClientCount[preferredJob] < preferredJob.MaxNumber)
|
||||||
|
{
|
||||||
|
c.assignedJob = preferredJob;
|
||||||
|
assignedClientCount[preferredJob]++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//none of the jobs the client prefers are available anymore
|
||||||
|
else if (preferredJob == c.jobPreferences.Last())
|
||||||
|
{
|
||||||
|
//find all jobs that are still available
|
||||||
|
var remainingJobs = JobPrefab.List.FindAll(jp => assignedClientCount[preferredJob] < jp.MaxNumber);
|
||||||
|
|
||||||
//if there's enough crew members assigned to the job already, continue
|
//all jobs taken, give a random job
|
||||||
if (assignedClientCount[jobIndex] >= JobPrefab.List[jobIndex].MaxNumber) continue;
|
if (remainingJobs.Count == 0)
|
||||||
|
{
|
||||||
unassigned[i].assignedJob = JobPrefab.List[jobIndex];
|
DebugConsole.ThrowError("Failed to assign a suitable job for \"" + c.name + "\" (all jobs already have the maximum numbers of players). Assigning a random job...");
|
||||||
|
c.assignedJob = JobPrefab.List[Rand.Range(0, JobPrefab.List.Count)];
|
||||||
assignedClientCount[jobIndex]++;
|
assignedClientCount[c.assignedJob]++;
|
||||||
unassigned.RemoveAt(i);
|
}
|
||||||
break;
|
else //some jobs still left, choose one of them by random
|
||||||
|
{
|
||||||
|
c.assignedJob = remainingJobs[Rand.Range(0, remainingJobs.Count)];
|
||||||
|
assignedClientCount[c.assignedJob]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user