Merge pull request #1321 from DogooFalchion/ssc_join_inv
Enable user to upload their data from when they join as SSC
This commit is contained in:
commit
7d323f253a
5 changed files with 182 additions and 18 deletions
|
|
@ -298,6 +298,10 @@ namespace TShockAPI
|
||||||
{
|
{
|
||||||
HelpText = "Saves all serverside characters."
|
HelpText = "Saves all serverside characters."
|
||||||
});
|
});
|
||||||
|
add(new Command(Permissions.uploaddata, UploadJoinData, "uploadssc")
|
||||||
|
{
|
||||||
|
HelpText = "Upload the account information when you joined the server as your Server Side Character data."
|
||||||
|
});
|
||||||
add(new Command(Permissions.settempgroup, TempGroup, "tempgroup")
|
add(new Command(Permissions.settempgroup, TempGroup, "tempgroup")
|
||||||
{
|
{
|
||||||
HelpText = "Temporarily sets another player's group."
|
HelpText = "Temporarily sets another player's group."
|
||||||
|
|
@ -1686,6 +1690,63 @@ namespace TShockAPI
|
||||||
args.Player.SendSuccessMessage("SSC of player \"{0}\" has been overriden.", matchedPlayer.Name);
|
args.Player.SendSuccessMessage("SSC of player \"{0}\" has been overriden.", matchedPlayer.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void UploadJoinData(CommandArgs args)
|
||||||
|
{
|
||||||
|
TSPlayer targetPlayer = args.Player;
|
||||||
|
if (args.Parameters.Count == 1 && args.Player.HasPermission(Permissions.uploadothersdata))
|
||||||
|
{
|
||||||
|
List<TSPlayer> players = TShock.Utils.FindPlayer(args.Parameters[0]);
|
||||||
|
if (players.Count > 1)
|
||||||
|
{
|
||||||
|
TShock.Utils.SendMultipleMatchError(args.Player, players.Select(p => p.Name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (players.Count == 0)
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("No player was found matching'{0}'", args.Parameters[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetPlayer = players[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Parameters.Count == 1)
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("You do not have permission to upload another player's data.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (args.Parameters.Count > 0)
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("Usage: /uploadssc [playername]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (args.Parameters.Count == 0 && args.Player is TSServerPlayer)
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("A console can not upload their player data.");
|
||||||
|
args.Player.SendErrorMessage("Usage: /uploadssc [playername]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetPlayer.IsLoggedIn)
|
||||||
|
{
|
||||||
|
if (TShock.CharacterDB.InsertSpecificPlayerData(targetPlayer, targetPlayer.DataWhenJoined))
|
||||||
|
{
|
||||||
|
targetPlayer.DataWhenJoined.RestoreCharacter(targetPlayer);
|
||||||
|
targetPlayer.SendSuccessMessage("Your Join Data has been uploaded to the server.");
|
||||||
|
args.Player.SendSuccessMessage("The player's data was successfully uploaded.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("Failed to upload your data, are you logged in to an account?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
args.Player.SendErrorMessage("The target player has not logged in yet.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void ForceHalloween(CommandArgs args)
|
private static void ForceHalloween(CommandArgs args)
|
||||||
{
|
{
|
||||||
TShock.Config.ForceHalloween = !TShock.Config.ForceHalloween;
|
TShock.Config.ForceHalloween = !TShock.Config.ForceHalloween;
|
||||||
|
|
|
||||||
|
|
@ -131,15 +131,15 @@ namespace TShockAPI.DB
|
||||||
string initialItems = String.Join("~", items.Take(NetItem.MaxInventory));
|
string initialItems = String.Join("~", items.Take(NetItem.MaxInventory));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
database.Query("INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY, questsCompleted) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8);",
|
database.Query("INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, spawnX, spawnY, questsCompleted) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8);",
|
||||||
user.ID,
|
user.ID,
|
||||||
TShock.ServerSideCharacterConfig.StartingHealth,
|
TShock.ServerSideCharacterConfig.StartingHealth,
|
||||||
TShock.ServerSideCharacterConfig.StartingHealth,
|
TShock.ServerSideCharacterConfig.StartingHealth,
|
||||||
TShock.ServerSideCharacterConfig.StartingMana,
|
TShock.ServerSideCharacterConfig.StartingMana,
|
||||||
TShock.ServerSideCharacterConfig.StartingMana,
|
TShock.ServerSideCharacterConfig.StartingMana,
|
||||||
initialItems,
|
initialItems,
|
||||||
-1,
|
-1,
|
||||||
-1,
|
-1,
|
||||||
0);
|
0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -159,7 +159,7 @@ namespace TShockAPI.DB
|
||||||
public bool InsertPlayerData(TSPlayer player)
|
public bool InsertPlayerData(TSPlayer player)
|
||||||
{
|
{
|
||||||
PlayerData playerData = player.PlayerData;
|
PlayerData playerData = player.PlayerData;
|
||||||
|
|
||||||
if (!player.IsLoggedIn)
|
if (!player.IsLoggedIn)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -219,5 +219,95 @@ namespace TShockAPI.DB
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Inserts a specific PlayerData into the SSC table for a player.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player">The player to store the data for.</param>
|
||||||
|
/// <param name="data">The player data to store.</param>
|
||||||
|
/// <returns>If the command succeeds.</returns>
|
||||||
|
public bool InsertSpecificPlayerData(TSPlayer player, PlayerData data)
|
||||||
|
{
|
||||||
|
PlayerData playerData = data;
|
||||||
|
|
||||||
|
if (!player.IsLoggedIn)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (player.HasPermission(Permissions.bypassssc))
|
||||||
|
{
|
||||||
|
TShock.Log.ConsoleInfo("Skipping SSC Backup for " + player.User.Name); // Debug code
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetPlayerData(player, player.User.ID).exists)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database.Query(
|
||||||
|
"INSERT INTO tsCharacter (Account, Health, MaxHealth, Mana, MaxMana, Inventory, extraSlot, spawnX, spawnY, skinVariant, hair, hairDye, hairColor, pantsColor, shirtColor, underShirtColor, shoeColor, hideVisuals, skinColor, eyeColor, questsCompleted) VALUES (@0, @1, @2, @3, @4, @5, @6, @7, @8, @9, @10, @11, @12, @13, @14, @15, @16, @17, @18, @19, @20);",
|
||||||
|
player.User.ID,
|
||||||
|
playerData.health,
|
||||||
|
playerData.maxHealth,
|
||||||
|
playerData.mana,
|
||||||
|
playerData.maxMana,
|
||||||
|
String.Join("~", playerData.inventory),
|
||||||
|
playerData.extraSlot,
|
||||||
|
playerData.spawnX,
|
||||||
|
playerData.spawnX,
|
||||||
|
playerData.skinVariant,
|
||||||
|
playerData.hair,
|
||||||
|
playerData.hairDye,
|
||||||
|
TShock.Utils.EncodeColor(playerData.hairColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.pantsColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.shirtColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.underShirtColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.shoeColor),
|
||||||
|
TShock.Utils.EncodeBoolArray(playerData.hideVisuals),
|
||||||
|
TShock.Utils.EncodeColor(playerData.skinColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.eyeColor),
|
||||||
|
playerData.questsCompleted);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
TShock.Log.Error(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
database.Query(
|
||||||
|
"UPDATE tsCharacter SET Health = @0, MaxHealth = @1, Mana = @2, MaxMana = @3, Inventory = @4, spawnX = @6, spawnY = @7, hair = @8, hairDye = @9, hairColor = @10, pantsColor = @11, shirtColor = @12, underShirtColor = @13, shoeColor = @14, hideVisuals = @15, skinColor = @16, eyeColor = @17, questsCompleted = @18, skinVariant = @19, extraSlot = @20 WHERE Account = @5;",
|
||||||
|
playerData.health,
|
||||||
|
playerData.maxHealth,
|
||||||
|
playerData.mana,
|
||||||
|
playerData.maxMana,
|
||||||
|
String.Join("~", playerData.inventory),
|
||||||
|
player.User.ID,
|
||||||
|
playerData.spawnX,
|
||||||
|
playerData.spawnX,
|
||||||
|
playerData.skinVariant,
|
||||||
|
playerData.hair,
|
||||||
|
playerData.hairDye,
|
||||||
|
TShock.Utils.EncodeColor(playerData.hairColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.pantsColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.shirtColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.underShirtColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.shoeColor),
|
||||||
|
TShock.Utils.EncodeBoolArray(playerData.hideVisuals),
|
||||||
|
TShock.Utils.EncodeColor(playerData.skinColor),
|
||||||
|
TShock.Utils.EncodeColor(playerData.eyeColor),
|
||||||
|
playerData.questsCompleted,
|
||||||
|
playerData.extraSlot ?? 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
TShock.Log.Error(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1506,6 +1506,8 @@ namespace TShockAPI
|
||||||
private static bool HandleConnecting(GetDataHandlerArgs args)
|
private static bool HandleConnecting(GetDataHandlerArgs args)
|
||||||
{
|
{
|
||||||
var user = TShock.Users.GetUserByName(args.Player.Name);
|
var user = TShock.Users.GetUserByName(args.Player.Name);
|
||||||
|
args.Player.DataWhenJoined = new PlayerData(args.Player);
|
||||||
|
args.Player.DataWhenJoined.CopyCharacter(args.Player);
|
||||||
|
|
||||||
if (user != null && !TShock.Config.DisableUUIDLogin)
|
if (user != null && !TShock.Config.DisableUUIDLogin)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,12 @@ namespace TShockAPI
|
||||||
[Description("User can save all the players SSI state.")]
|
[Description("User can save all the players SSI state.")]
|
||||||
public static readonly string savessc = "tshock.admin.savessi";
|
public static readonly string savessc = "tshock.admin.savessi";
|
||||||
|
|
||||||
|
[Description("User can upload their joined character data as SSC data.")]
|
||||||
|
public static readonly string uploaddata = "tshock.ssc.upload";
|
||||||
|
|
||||||
|
[Description("User can upload other players join data to the SSC database.")]
|
||||||
|
public static readonly string uploadothersdata = "tshock.ssc.upload.others";
|
||||||
|
|
||||||
[Description("User can elevate other users' groups temporarily.")]
|
[Description("User can elevate other users' groups temporarily.")]
|
||||||
public static readonly string settempgroup = "tshock.admin.tempgroup";
|
public static readonly string settempgroup = "tshock.admin.tempgroup";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ namespace TShockAPI
|
||||||
/// The amount of tiles that the player has killed in the last second.
|
/// The amount of tiles that the player has killed in the last second.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TileKillThreshold { get; set; }
|
public int TileKillThreshold { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of tiles the player has placed in the last second.
|
/// The amount of tiles the player has placed in the last second.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -113,10 +113,10 @@ namespace TShockAPI
|
||||||
/// A system to delay Remembered Position Teleports a few seconds
|
/// A system to delay Remembered Position Teleports a few seconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int RPPending = 0;
|
public int RPPending = 0;
|
||||||
|
|
||||||
public int sX = -1;
|
public int sX = -1;
|
||||||
public int sY = -1;
|
public int sY = -1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A queue of tiles destroyed by the player for reverting.
|
/// A queue of tiles destroyed by the player for reverting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -145,7 +145,7 @@ namespace TShockAPI
|
||||||
/// The player's temporary group. This overrides the user's actual group.
|
/// The player's temporary group. This overrides the user's actual group.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Group tempGroup = null;
|
public Group tempGroup = null;
|
||||||
|
|
||||||
public Timer tempGroupTimer;
|
public Timer tempGroupTimer;
|
||||||
|
|
||||||
private Group group = null;
|
private Group group = null;
|
||||||
|
|
@ -158,7 +158,7 @@ namespace TShockAPI
|
||||||
public int Index { get; protected set; }
|
public int Index { get; protected set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last time the player changed their team or pvp status.
|
/// The last time the player changed their team or pvp status.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime LastPvPTeamChange;
|
public DateTime LastPvPTeamChange;
|
||||||
|
|
||||||
|
|
@ -175,7 +175,7 @@ namespace TShockAPI
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of command callbacks indexed by the command they need to do.
|
/// A list of command callbacks indexed by the command they need to do.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, Action<object>> AwaitingResponse;
|
public Dictionary<string, Action<object>> AwaitingResponse;
|
||||||
|
|
||||||
public bool AwaitingName { get; set; }
|
public bool AwaitingName { get; set; }
|
||||||
|
|
||||||
|
|
@ -314,14 +314,14 @@ namespace TShockAPI
|
||||||
/// Spawn protection message cool down.
|
/// Spawn protection message cool down.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long SPm = 1;
|
public long SPm = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Permission to build message cool down.
|
/// Permission to build message cool down.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long BPm = 1;
|
public long BPm = 1;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The time in ms when the player has logged in.
|
/// The time in ms when the player has logged in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public long LoginMS;
|
public long LoginMS;
|
||||||
|
|
||||||
|
|
@ -354,7 +354,7 @@ namespace TShockAPI
|
||||||
/// Contains data stored by plugins
|
/// Contains data stored by plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected ConcurrentDictionary<string, object> data = new ConcurrentDictionary<string, object>();
|
protected ConcurrentDictionary<string, object> data = new ConcurrentDictionary<string, object>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the player is a real, human, player on the server.
|
/// Whether the player is a real, human, player on the server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -573,6 +573,11 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This contains the character data a player has when they join the server.
|
||||||
|
/// </summary>
|
||||||
|
public PlayerData DataWhenJoined { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the player's storage contains the given key.
|
/// Determines whether the player's storage contains the given key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -727,7 +732,7 @@ namespace TShockAPI
|
||||||
/// Spawns the player at his spawn point.
|
/// Spawns the player at his spawn point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Spawn()
|
public void Spawn()
|
||||||
{
|
{
|
||||||
if (this.sX > 0 && this.sY > 0)
|
if (this.sX > 0 && this.sY > 0)
|
||||||
{
|
{
|
||||||
Spawn(this.sX, this.sY);
|
Spawn(this.sX, this.sY);
|
||||||
|
|
@ -839,7 +844,7 @@ namespace TShockAPI
|
||||||
/// <returns>True or false, depending if the item passed the check or not.</returns>
|
/// <returns>True or false, depending if the item passed the check or not.</returns>
|
||||||
public bool GiveItemCheck(int type, string name, int width, int height, int stack, int prefix = 0)
|
public bool GiveItemCheck(int type, string name, int width, int height, int stack, int prefix = 0)
|
||||||
{
|
{
|
||||||
if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) &&
|
if ((TShock.Itembans.ItemIsBanned(name) && TShock.Config.PreventBannedItemSpawn) &&
|
||||||
(TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems))
|
(TShock.Itembans.ItemIsBanned(name, this) || !TShock.Config.AllowAllowedGroupsToSpawnBannedItems))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
@ -955,7 +960,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a message with the specified color.
|
/// Sends a message with the specified color.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="msg">The message.</param>
|
/// <param name="msg">The message.</param>
|
||||||
/// <param name="color">The message color.</param>
|
/// <param name="color">The message color.</param>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue