Anton Tarasenko
3 years ago
4 changed files with 571 additions and 0 deletions
@ -0,0 +1,51 @@ |
|||||||
|
[default FutilityNicknames] |
||||||
|
; This feature allows to configure nickname limitations for the server. |
||||||
|
; It allows you to customize vanilla limitations for nickname length and |
||||||
|
; color with those of your own design. Enabling this feature overwrites |
||||||
|
; default behaviour. |
||||||
|
autoEnable=true |
||||||
|
; How to treat whitespace characters inside players' nicknames. |
||||||
|
; * `NSA_DoNothing` - does nothing, leaving whitespaces as they are; |
||||||
|
; * `NSA_Trim` - removes leading and trailing whitespaces for nicknames; |
||||||
|
; * `NSA_Simplify` - removes leading and trailing whitespaces |
||||||
|
; for nicknames, also reducing a sequence of whitespaces inside |
||||||
|
; nickname to a single space, e.g. "my nick" becomes "my nick". |
||||||
|
; Default is `NSA_DoNothing`, same as on vanilla. |
||||||
|
spacesAction=NSA_DoNothing |
||||||
|
; How to treat colored nicknames. |
||||||
|
; * `NCP_ForbidColor` - completely strips down any color from nicknames; |
||||||
|
; * `NCP_ForceTeamColor` - forces all nicknames to have player's current |
||||||
|
; team's color; |
||||||
|
; * `NCP_ForceSingleColor` - allows nickname to be painted with a single |
||||||
|
; color (sets nickname's color to that of the first character); |
||||||
|
; * `NCP_AllowAnyColor` - allows nickname to be colored in any way player |
||||||
|
; wants. |
||||||
|
; Default is `NCP_ForbidColor`, same as on vanilla. |
||||||
|
colorPermissions=NCP_ForbidColor |
||||||
|
; Set this to `true` if you wish to replace all whitespace characters with |
||||||
|
; underscores and `false` to leave them as is. |
||||||
|
; Default is `true`, same as on vanilla. However there is one difference: |
||||||
|
; Futility replaces all whitespace characters (including tabulations, |
||||||
|
; non-breaking spaces, etc.) instead of only ' '. |
||||||
|
replaceSpacesWithUnderscores=true |
||||||
|
; Max allowed nickname length. Negative values disable any length limits. |
||||||
|
; |
||||||
|
; NOTE: `0` resets all nicknames to be empty and, if `correctEmptyNicknames` |
||||||
|
; is set to `true`, they will be replaced with one of the fallback nicknames |
||||||
|
; (see `correctEmptyNicknames` and `fallbackNickname`). |
||||||
|
maxNicknameLength=20 |
||||||
|
; Should we replace empty player nicknames with a random fallback nickname |
||||||
|
; (defined in `fallbackNickname` array)? |
||||||
|
correctEmptyNicknames=true |
||||||
|
; Array of fallback nicknames that will be used to replace any empty nicknames |
||||||
|
; if `correctEmptyNicknames` is set to `true`. |
||||||
|
fallbackNickname="Fresh Meat" |
||||||
|
fallbackNickname="Rotten Meat" |
||||||
|
fallbackNickname="Troll Meat" |
||||||
|
fallbackNickname="Rat Meat" |
||||||
|
fallbackNickname="Dog Meat" |
||||||
|
fallbackNickname="Elk Meat" |
||||||
|
fallbackNickname="Crab Meat" |
||||||
|
fallbackNickname="Boar Meat" |
||||||
|
fallbackNickname="Horker Meat" |
||||||
|
fallbackNickname="Bug Meat" |
@ -0,0 +1,179 @@ |
|||||||
|
/** |
||||||
|
* Config object for `FutileNickames_Feature`. |
||||||
|
* Copyright 2022 Anton Tarasenko |
||||||
|
*------------------------------------------------------------------------------ |
||||||
|
* This file is part of Acedia. |
||||||
|
* |
||||||
|
* Acedia is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* Acedia is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class FutileNickames extends FeatureConfig |
||||||
|
perobjectconfig |
||||||
|
config(FutilityNicknames); |
||||||
|
|
||||||
|
enum NicknameSpacesAction |
||||||
|
{ |
||||||
|
NSA_DoNothing, |
||||||
|
NSA_Trim, |
||||||
|
NSA_Simplify |
||||||
|
}; |
||||||
|
|
||||||
|
enum NicknameColorPermissions |
||||||
|
{ |
||||||
|
NCP_ForbidColor, |
||||||
|
NCP_ForceTeamColor, |
||||||
|
NCP_ForceSingleColor, |
||||||
|
NCP_AllowAnyColor |
||||||
|
}; |
||||||
|
|
||||||
|
var public config NicknameSpacesAction spacesAction; |
||||||
|
var public config NicknameColorPermissions colorPermissions; |
||||||
|
var public config bool replaceSpacesWithUnderscores; |
||||||
|
var public config bool correctEmptyNicknames; |
||||||
|
var public config int maxNicknameLength; |
||||||
|
var public config array<string> fallbackNickname; |
||||||
|
|
||||||
|
protected function AssociativeArray ToData() |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local DynamicArray fallbackNicknamesData; |
||||||
|
local AssociativeArray data; |
||||||
|
data = __().collections.EmptyAssociativeArray(); |
||||||
|
data.SetItem( P("spacesAction"), |
||||||
|
_.text.FromString(string(spacesAction)), true); |
||||||
|
data.SetItem( P("colorPermissions"), |
||||||
|
_.text.FromString(string(colorPermissions)), true); |
||||||
|
data.SetBool( P("replaceSpacesWithUnderscores"), |
||||||
|
replaceSpacesWithUnderscores, true); |
||||||
|
data.SetBool(P("correctEmptyNicknames"), correctEmptyNicknames, true); |
||||||
|
data.SetInt(P("maxNicknameLength"), maxNicknameLength, true); |
||||||
|
fallbackNicknamesData = __().collections.EmptyDynamicArray(); |
||||||
|
for (i = 0; i < fallbackNickname.length; i += 1) |
||||||
|
{ |
||||||
|
fallbackNicknamesData.AddItem( |
||||||
|
__().text.FromFormattedString(fallbackNickname[i]), true); |
||||||
|
} |
||||||
|
data.SetItem(P("fallbackNickname"), fallbackNicknamesData, true); |
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
protected function FromData(AssociativeArray source) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local Text nextNickName; |
||||||
|
local DynamicArray fallbackNicknamesData; |
||||||
|
if (source == none) { |
||||||
|
return; |
||||||
|
} |
||||||
|
spacesAction = SpaceActionFromText(source.GetText(P("spacesAction"))); |
||||||
|
colorPermissions = ColorPermissionsFromText( |
||||||
|
source.GetText(P("colorPermissions"))); |
||||||
|
replaceSpacesWithUnderscores = |
||||||
|
source.GetBool(P("replaceSpacesWithUnderscores"), true); |
||||||
|
correctEmptyNicknames = source.GetBool(P("correctEmptyNicknames"), true); |
||||||
|
maxNicknameLength = source.GetInt(P("correctEmptyNicknames"), 20); |
||||||
|
fallbackNicknamesData = DynamicArray(source.GetItem(P("fallbackNickname"))); |
||||||
|
if (fallbackNickname.length > 0) { |
||||||
|
fallbackNickname.length = 0; |
||||||
|
} |
||||||
|
for (i = 0; i < fallbackNicknamesData.GetLength(); i += 1) |
||||||
|
{ |
||||||
|
nextNickName = fallbackNicknamesData.GetText(i); |
||||||
|
if (nextNickName != none) { |
||||||
|
fallbackNickname[i] = nextNickName.ToFormattedString(); |
||||||
|
} |
||||||
|
else { |
||||||
|
fallbackNickname[i] = ""; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function NicknameSpacesAction SpaceActionFromText(Text action) |
||||||
|
{ |
||||||
|
if (action == none) { |
||||||
|
return NSA_DoNothing; |
||||||
|
} |
||||||
|
if (action.EndsWith(P("DoNothing"), SCASE_INSENSITIVE)) { |
||||||
|
return NSA_DoNothing; |
||||||
|
} |
||||||
|
if (action.EndsWith(P("Trim"), SCASE_INSENSITIVE)) { |
||||||
|
return NSA_Trim; |
||||||
|
} |
||||||
|
if (action.EndsWith(P("Simplify"), SCASE_INSENSITIVE)) { |
||||||
|
return NSA_Simplify; |
||||||
|
} |
||||||
|
return NSA_DoNothing; |
||||||
|
} |
||||||
|
|
||||||
|
private function NicknameColorPermissions ColorPermissionsFromText( |
||||||
|
Text permissions) |
||||||
|
{ |
||||||
|
if (permissions == none) { |
||||||
|
return NCP_ForbidColor; |
||||||
|
} |
||||||
|
if (permissions.EndsWith(P("ForbidColor"), SCASE_INSENSITIVE)) { |
||||||
|
return NCP_ForbidColor; |
||||||
|
} |
||||||
|
if (permissions.EndsWith(P("TeamColor"), SCASE_INSENSITIVE)) { |
||||||
|
return NCP_ForceTeamColor; |
||||||
|
} |
||||||
|
if (permissions.EndsWith(P("SingleColor"), SCASE_INSENSITIVE)) { |
||||||
|
return NCP_ForceSingleColor; |
||||||
|
} |
||||||
|
if (permissions.EndsWith(P("AllowAnyColor"), SCASE_INSENSITIVE)) { |
||||||
|
return NCP_AllowAnyColor; |
||||||
|
} |
||||||
|
return NCP_ForbidColor; |
||||||
|
} |
||||||
|
|
||||||
|
protected function DefaultIt() |
||||||
|
{ |
||||||
|
spacesAction = NSA_DoNothing; |
||||||
|
colorPermissions = NCP_ForbidColor; |
||||||
|
replaceSpacesWithUnderscores = true; |
||||||
|
correctEmptyNicknames = true; |
||||||
|
maxNicknameLength = 20; |
||||||
|
if (fallbackNickname.length > 0) { |
||||||
|
fallbackNickname.length = 0; |
||||||
|
} |
||||||
|
fallbackNickname[0] = "Fresh Meat"; |
||||||
|
fallbackNickname[1] = "Rotten Meat"; |
||||||
|
fallbackNickname[2] = "Troll Meat"; |
||||||
|
fallbackNickname[3] = "Rat Meat"; |
||||||
|
fallbackNickname[4] = "Dog Meat"; |
||||||
|
fallbackNickname[5] = "Elk Meat"; |
||||||
|
fallbackNickname[6] = "Crab Meat"; |
||||||
|
fallbackNickname[7] = "Boar Meat"; |
||||||
|
fallbackNickname[8] = "Horker Meat"; |
||||||
|
fallbackNickname[9] = "Bug Meat"; |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
configName = "FutilityNicknames" |
||||||
|
spacesAction = NSA_DoNothing |
||||||
|
colorPermissions = NCP_ForbidColor |
||||||
|
replaceSpacesWithUnderscores = true |
||||||
|
correctEmptyNicknames = true |
||||||
|
maxNicknameLength = 20 |
||||||
|
fallbackNickname(0) = "Fresh Meat" |
||||||
|
fallbackNickname(1) = "Rotten Meat" |
||||||
|
fallbackNickname(2) = "Troll Meat" |
||||||
|
fallbackNickname(3) = "Rat Meat" |
||||||
|
fallbackNickname(4) = "Dog Meat" |
||||||
|
fallbackNickname(5) = "Elk Meat" |
||||||
|
fallbackNickname(6) = "Crab Meat" |
||||||
|
fallbackNickname(7) = "Boar Meat" |
||||||
|
fallbackNickname(8) = "Horker Meat" |
||||||
|
fallbackNickname(9) = "Bug Meat" |
||||||
|
} |
@ -0,0 +1,340 @@ |
|||||||
|
/** |
||||||
|
* This feature allows to configure nickname limitations for the server. |
||||||
|
* It allows you to customize vanilla limitations for nickname length and |
||||||
|
* color with those of your own design. Enabling this feature overwrites |
||||||
|
* default behaviour. |
||||||
|
* Copyright 2022 Anton Tarasenko |
||||||
|
*------------------------------------------------------------------------------ |
||||||
|
* This file is part of Acedia. |
||||||
|
* |
||||||
|
* Acedia is free software: you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation, version 3 of the License, or |
||||||
|
* (at your option) any later version. |
||||||
|
* |
||||||
|
* Acedia is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with Acedia. If not, see <https://www.gnu.org/licenses/>. |
||||||
|
*/ |
||||||
|
class FutileNickames_Feature extends Feature |
||||||
|
dependson(FutileNickames); |
||||||
|
|
||||||
|
/** |
||||||
|
* This feature's functionality is rather simple, but we will still break up |
||||||
|
* what its various components are. |
||||||
|
* |
||||||
|
* Fallback nicknames are picked at random from |
||||||
|
* the `fallbackNicknames` array. This is done by copying that array into |
||||||
|
* `unusedNicknames` and then picking and removing its random elements each |
||||||
|
* time we need a fallback. Once `unusedNicknames` is empty - it is copied from |
||||||
|
* `fallbackNicknames` once again, letting already used nicknames to be reused. |
||||||
|
* `unusedNicknames` contains same references as `fallbackNicknames`, |
||||||
|
* so they need to be separately deallocated and should also be forgotten once |
||||||
|
* `fallbackNicknames` are deallocated`. |
||||||
|
* This is implemented inside `PickNextFallback()` method. |
||||||
|
* |
||||||
|
* Nickname changes are applied inside `CensorNickname()` method that uses |
||||||
|
* several auxiliary methods to perform different stages of "censoring". |
||||||
|
* Censoring is performed: |
||||||
|
* 1. On any player's name change |
||||||
|
* (using `OnPlayerNameChanging()` signal, connected to |
||||||
|
* `HandleNicknameChange()`); |
||||||
|
* 2. When new player logins (using `OnNewPlayer()` signal, |
||||||
|
* conneted to `CensorOriginalNickname()`) to enforce our own |
||||||
|
* handling of player's original nickname; |
||||||
|
* 3. When censoring is re-activated. |
||||||
|
* In case all censoring options of this feature are disabled |
||||||
|
* (checked by `IsAnyCensoringEnabled()`) - we do not attempt to |
||||||
|
* catch any events or do anything at all. |
||||||
|
* If settings change mid-execution, this feature might need to |
||||||
|
* enable or disable censoring on-the-fly. To accomplish that we |
||||||
|
* remember current status inside `censoringNicknames` boolean |
||||||
|
* variable and enable/disable events if required by settings. |
||||||
|
* So whenever we re-activate censoring we also need to update |
||||||
|
* ("censor") current players' nicknames - a third occasion to |
||||||
|
* call `CensorNickname()`, implemented inside |
||||||
|
* `CensorCurrentPlayersNicknames()`. |
||||||
|
*/ |
||||||
|
|
||||||
|
// How to treat whitespace characters inside players' nicknames. |
||||||
|
// * `NSA_DoNothing` - does nothing, leaving whitespaces as they are; |
||||||
|
// * `NSA_Trim` - removes leading and trailing whitespaces for nicknames; |
||||||
|
// * `NSA_Simplify` - removes leading and trailing whitespaces |
||||||
|
// for nicknames, also reducing a sequence of whitespaces inside |
||||||
|
// nickname to a single space, e.g. "my nick" becomes "my nick". |
||||||
|
// Default is `NSA_DoNothing`, same as on vanilla. |
||||||
|
var private /*config*/ FutileNickames.NicknameSpacesAction spacesAction; |
||||||
|
|
||||||
|
// How to treat colored nicknames. |
||||||
|
// * `NCP_ForbidColor` - completely strips down any color from nicknames; |
||||||
|
// * `NCP_ForceTeamColor` - forces all nicknames to have player's current |
||||||
|
// team's color; |
||||||
|
// * `NCP_ForceSingleColor` - allows nickname to be painted with a single |
||||||
|
// color (sets nickname's color to that of the first character); |
||||||
|
// * `NCP_AllowAnyColor` - allows nickname to be colored in any way player |
||||||
|
// wants. |
||||||
|
// Default is `NCP_ForbidColor`, same as on vanilla. |
||||||
|
var private /*config*/ FutileNickames.NicknameColorPermissions colorPermissions; |
||||||
|
|
||||||
|
// Set this to `true` if you wish to replace all whitespace characters with |
||||||
|
// underscores and `false` to leave them as is. |
||||||
|
// Default is `true`, same as on vanilla. However there is one difference: |
||||||
|
// Futility replaces all whitespace characters (including tabulations, |
||||||
|
// non-breaking spaces, etc.) instead of only ' '. |
||||||
|
var private /*config*/ bool replaceSpacesWithUnderscores; |
||||||
|
|
||||||
|
// Max allowed nickname length. Negative values disable any length limits. |
||||||
|
// |
||||||
|
// NOTE: `0` resets all nicknames to be empty and, if `correctEmptyNicknames` |
||||||
|
// is set to `true`, they will be replaced with one of the fallback nicknames |
||||||
|
// (see `correctEmptyNicknames` and `fallbackNickname`). |
||||||
|
var private /*config*/ int maxNicknameLength; |
||||||
|
|
||||||
|
// Should we replace empty player nicknames with a random fallback nickname |
||||||
|
// (defined in `fallbackNickname` array)? |
||||||
|
var private /*config*/ bool correctEmptyNicknames; |
||||||
|
// Array of fallback nicknames that will be used to replace any empty nicknames |
||||||
|
// if `correctEmptyNicknames` is set to `true`. |
||||||
|
var private /*config*/ array<Text> fallbackNickname; |
||||||
|
|
||||||
|
// Guaranteed order of applying changes (only chosen ones) is as following: |
||||||
|
// 1. Trim/simplify spaces; |
||||||
|
// 2. Enforce max limit of nickname's length; |
||||||
|
// 3. Replace empty nickname with fallback nickname (no further changes |
||||||
|
// will be applied to fallback nickname in that case); |
||||||
|
// 4. Enforce color limitation; |
||||||
|
// 5. Replace remaining whitespaces with underscores. |
||||||
|
// |
||||||
|
// NOTE #1: as follows from the instruction described above, no changes will |
||||||
|
// ever be applied to fallback nicknames (unless player's nickname |
||||||
|
// coincides with one by pure accident). |
||||||
|
// NOTE #2: whitespaces inside steam nicknames are converted into underscores |
||||||
|
// before they are passed into the game and this is a change Futility |
||||||
|
// cannot currently abort. |
||||||
|
// Therefore all changes relevant to whitespaces inside nicknames will only |
||||||
|
// be applied to in-game changes. |
||||||
|
|
||||||
|
// Nicknames from `fallbackNickname` that can still be picked in |
||||||
|
// the current rotation. |
||||||
|
var private array<Text> unusedNicknames; |
||||||
|
// Are we currently censoring nicknames? |
||||||
|
// Set to `false` if none of the feature's options require |
||||||
|
// any action (censoring) and, therefore, we do not listen to any signals. |
||||||
|
var private bool censoringNicknames; |
||||||
|
|
||||||
|
var private const int CODEPOINT_UNDERSCORE; |
||||||
|
|
||||||
|
protected function OnDisabled() |
||||||
|
{ |
||||||
|
_.memory.FreeMany(fallbackNickname); |
||||||
|
// Free this `Text` data - it will be refilled with `SwapConfig()` |
||||||
|
// if this feature is ever reenabled |
||||||
|
if (fallbackNickname.length > 0) |
||||||
|
{ |
||||||
|
_.memory.FreeMany(fallbackNickname); |
||||||
|
fallbackNickname.length = 0; |
||||||
|
unusedNicknames.length = 0; |
||||||
|
} |
||||||
|
if (censoringNicknames) |
||||||
|
{ |
||||||
|
censoringNicknames = false; |
||||||
|
_.players.OnPlayerNameChanging(self).Disconnect(); |
||||||
|
_.players.OnNewPlayer(self).Disconnect(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected function SwapConfig(FeatureConfig config) |
||||||
|
{ |
||||||
|
local bool configRequiresCensoring; |
||||||
|
local FutileNickames newConfig; |
||||||
|
newConfig = FutileNickames(config); |
||||||
|
if (newConfig == none) { |
||||||
|
return; |
||||||
|
} |
||||||
|
replaceSpacesWithUnderscores = newConfig.replaceSpacesWithUnderscores; |
||||||
|
correctEmptyNicknames = newConfig.correctEmptyNicknames; |
||||||
|
spacesAction = newConfig.spacesAction; |
||||||
|
colorPermissions = newConfig.colorPermissions; |
||||||
|
maxNicknameLength = newConfig.maxNicknameLength; |
||||||
|
configRequiresCensoring = IsAnyCensoringEnabled(); |
||||||
|
// Enable or disable censoring if `IsAnyCensoringEnabled()`'s response |
||||||
|
// has changed. |
||||||
|
if (!censoringNicknames && configRequiresCensoring) |
||||||
|
{ |
||||||
|
censoringNicknames = true; |
||||||
|
// Do this before adding event handler to |
||||||
|
// avoid censoring nicknames second time |
||||||
|
CensorCurrentPlayersNicknames(); |
||||||
|
_.players.OnPlayerNameChanging(self).connect = HandleNicknameChange; |
||||||
|
_.players.OnNewPlayer(self).connect = CensorOriginalNickname; |
||||||
|
} |
||||||
|
if (censoringNicknames && !configRequiresCensoring) |
||||||
|
{ |
||||||
|
censoringNicknames = false; |
||||||
|
_.players.OnPlayerNameChanging(self).Disconnect(); |
||||||
|
_.players.OnNewPlayer(self).Disconnect(); |
||||||
|
} |
||||||
|
SwapFallbackNicknames(newConfig); |
||||||
|
} |
||||||
|
|
||||||
|
private function Text PickNextFallback() |
||||||
|
{ |
||||||
|
local int pickedIndex; |
||||||
|
local Text result; |
||||||
|
if (fallbackNickname.length <= 0) |
||||||
|
{ |
||||||
|
// Just in case this feature is really misconfigured |
||||||
|
return P("Fresh Meat").Copy(); |
||||||
|
} |
||||||
|
if (unusedNicknames.length <= 0) { |
||||||
|
unusedNicknames = fallbackNickname; |
||||||
|
} |
||||||
|
// Pick one nickname at random. |
||||||
|
// `pickedIndex` will belong to [0; unusedNicknames.length - 1] segment. |
||||||
|
pickedIndex = Rand(unusedNicknames.length); |
||||||
|
result = unusedNicknames[pickedIndex].Copy(); |
||||||
|
unusedNicknames.Remove(pickedIndex, 1); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
protected function SwapFallbackNicknames(FutileNickames newConfig) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
_.memory.FreeMany(fallbackNickname); |
||||||
|
if (fallbackNickname.length > 0) { |
||||||
|
fallbackNickname.length = 0; |
||||||
|
} |
||||||
|
for (i = 0; i < newConfig.fallbackNickname.length; i += 1) |
||||||
|
{ |
||||||
|
fallbackNickname[i] = |
||||||
|
_.text.FromFormattedString(newConfig.fallbackNickname[i]); |
||||||
|
} |
||||||
|
unusedNicknames = fallbackNickname; |
||||||
|
} |
||||||
|
|
||||||
|
private function bool IsAnyCensoringEnabled() |
||||||
|
{ |
||||||
|
return ( replaceSpacesWithUnderscores |
||||||
|
|| correctEmptyNicknames |
||||||
|
|| maxNicknameLength >= 0 |
||||||
|
|| colorPermissions != NCP_AllowAnyColor |
||||||
|
|| spacesAction != NSA_DoNothing); |
||||||
|
} |
||||||
|
|
||||||
|
// For nickname changes mid-game. |
||||||
|
private function HandleNicknameChange( |
||||||
|
EPlayer affectedPlayer, |
||||||
|
Text oldName, |
||||||
|
MutableText newName) |
||||||
|
{ |
||||||
|
CensorNickname(newName, affectedPlayer); |
||||||
|
} |
||||||
|
|
||||||
|
// For handling of player's original nicknames. |
||||||
|
private function CensorOriginalNickname(EPlayer affectedPlayer) |
||||||
|
{ |
||||||
|
local Text originalNickname; |
||||||
|
if (affectedPlayer == none) { |
||||||
|
return; |
||||||
|
} |
||||||
|
originalNickname = affectedPlayer.GetOriginalName(); |
||||||
|
// This will automatically trigger `OnPlayerNameChanging()` signal and |
||||||
|
// our `HandleNicknameChange()` handler. |
||||||
|
affectedPlayer.SetName(originalNickname); |
||||||
|
_.memory.Free(originalNickname); |
||||||
|
} |
||||||
|
|
||||||
|
// For handling nicknames of players after censoring is re-activated by |
||||||
|
// config change. |
||||||
|
private function CensorCurrentPlayersNicknames() |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local Text nextNickname; |
||||||
|
local MutableText alteredNickname; |
||||||
|
local array<EPlayer> currentPlayers; |
||||||
|
currentPlayers = _.players.GetAll(); |
||||||
|
for (i = 0; i < currentPlayers.length; i += 1) |
||||||
|
{ |
||||||
|
nextNickname = currentPlayers[i].GetName(); |
||||||
|
alteredNickname = nextNickname.MutableCopy(); |
||||||
|
CensorNickname(alteredNickname, currentPlayers[i]); |
||||||
|
if (!alteredNickname.Compare(nextNickname)) { |
||||||
|
currentPlayers[i].SetName(alteredNickname); |
||||||
|
} |
||||||
|
_.memory.Free(alteredNickname); |
||||||
|
_.memory.Free(nextNickname); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function CensorNickname(MutableText nickname, EPlayer affectedPlayer) |
||||||
|
{ |
||||||
|
local Text fallback; |
||||||
|
local Text.Formatting newFormatting; |
||||||
|
if (nickname == none) return; |
||||||
|
if (affectedPlayer == none) return; |
||||||
|
|
||||||
|
if (spacesAction != NSA_DoNothing) { |
||||||
|
nickname.Simplify(spacesAction == NSA_Simplify); |
||||||
|
} |
||||||
|
if (maxNicknameLength >= 0) { |
||||||
|
nickname.Remove(maxNicknameLength); |
||||||
|
} |
||||||
|
if (correctEmptyNicknames && nickname.IsEmpty()) |
||||||
|
{ |
||||||
|
fallback = PickNextFallback(); |
||||||
|
nickname.Append(fallback); |
||||||
|
_.memory.Free(fallback); |
||||||
|
return; |
||||||
|
} |
||||||
|
if (colorPermissions != NCP_AllowAnyColor) |
||||||
|
{ |
||||||
|
if (colorPermissions == NCP_ForceSingleColor) { |
||||||
|
newFormatting = nickname.GetCharacter(0).formatting; |
||||||
|
} |
||||||
|
else if (colorPermissions == NCP_ForceTeamColor) |
||||||
|
{ |
||||||
|
newFormatting.isColored = true; |
||||||
|
newFormatting.color = affectedPlayer.GetTeamColor(); |
||||||
|
} |
||||||
|
// `colorPermissions == NCP_ForbidColor` |
||||||
|
// `newFormatting` is colorless by default |
||||||
|
nickname.ChangeFormatting(newFormatting); |
||||||
|
} |
||||||
|
if (replaceSpacesWithUnderscores) { |
||||||
|
ReplaceSpaces(nickname); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Asusmes `nickname != none`. |
||||||
|
private function ReplaceSpaces(MutableText nickname) |
||||||
|
{ |
||||||
|
local int i; |
||||||
|
local MutableText nicknameCopy; |
||||||
|
local Text.Character nextCharacter, underscoreCharacter; |
||||||
|
nicknameCopy = nickname.MutableCopy(); |
||||||
|
nickname.Clear(); |
||||||
|
underscoreCharacter = |
||||||
|
_.text.CharacterFromCodePoint(CODEPOINT_UNDERSCORE); |
||||||
|
for (i = 0; i < nicknameCopy.GetLength(); i += 1) |
||||||
|
{ |
||||||
|
nextCharacter = nicknameCopy.GetCharacter(i); |
||||||
|
if (_.text.IsWhitespace(nextCharacter)) |
||||||
|
{ |
||||||
|
// Replace character with underscore, leaving the formatting |
||||||
|
underscoreCharacter.formatting = nextCharacter.formatting; |
||||||
|
nextCharacter = underscoreCharacter; |
||||||
|
} |
||||||
|
nickname.AppendCharacter(nextCharacter); |
||||||
|
} |
||||||
|
_.memory.Free(nicknameCopy); |
||||||
|
} |
||||||
|
|
||||||
|
defaultproperties |
||||||
|
{ |
||||||
|
configClass = class'FutileNickames' |
||||||
|
CODEPOINT_UNDERSCORE = 95 // '_' |
||||||
|
} |
Loading…
Reference in new issue