Merge remote branch 'upstream/general-devel' into general-devel
This commit is contained in:
commit
d36a549e1e
82 changed files with 4844 additions and 5602 deletions
9
.editorconfig
Normal file
9
.editorconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = crlf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.cs]
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
* text=auto
|
||||
*.cs text eol=crlf
|
||||
*.sln text eol=crlf
|
||||
*.csproj text eol=crlf
|
||||
*.vsmdi text eol=crlf
|
||||
9
.travis.yml
Normal file
9
.travis.yml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
language: c
|
||||
install:
|
||||
- sudo apt-get install mono-devel mono-gmcs nunit-console
|
||||
script:
|
||||
- xbuild ./TShockAPI/TShockAPI.csproj
|
||||
notifications:
|
||||
irc: irc.rizon.net#tshock
|
||||
hipchat:
|
||||
secure: hpRLWiHF2j6O2qJOVs++aqAmryN6G5kY0SF26/rKCpQ7klhMlDZIgI1V1dbkKqlculFtW1neS0EBJyV9lmcV5b26H+KhlZYGN0j7q1VcOTM3rvtU6wW0Ap22uRLl2RrnA4kEsgDAsNouPOkyLZ19hlHAISlsId6G4+Rfqg6k+zQ=
|
||||
36
CONTRIBUTING
Normal file
36
CONTRIBUTING
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
### Issue Guidelines
|
||||
Please follow these simple requirements before posting an issue:
|
||||
|
||||
1. TShock version number
|
||||
2. Any stack traces that may have happened when the issue occurred
|
||||
3. How to reproduce the issue
|
||||
|
||||
### Pull Request Dev Guidelines
|
||||
|
||||
These guidelines are for contributors. If you do not follow these guidelines your commits will be reverted.
|
||||
|
||||
Required:
|
||||
- Follow the code style. We generally use microsofts except for m_ infront of private variables.
|
||||
- Do not push unfinished features to the master branch, instead create a remote branch and push to that.
|
||||
- Do not push untested code to the master branch, instead push to the test branch.
|
||||
- Document all compatibility issues in the COMPATIBILITY file. (IE file formats changing)
|
||||
- DO NOT MASS COMMIT. Commit changes as you go (without pushing). That way when you push we don't get a thousand changes with a 1-3 line commit message.
|
||||
|
||||
Optional:
|
||||
- Build Version Increment (http://autobuildversion.codeplex.com/).
|
||||
|
||||
----
|
||||
|
||||
### Dev Team Guidelines
|
||||
|
||||
These guidelines are to be followed by all developers with commit level access to this repository:
|
||||
|
||||
- Do not, for any reason, submit code to the master branch before it hits the development branch first. If the development branch is far ahead, and a new bug fix is going out, branch master, then merge with master and remove your branch.
|
||||
- If you are found to do this, you will be the person merging and rebasing your code to fit general-devel.
|
||||
- Prior to posting any version on the website, you must tick the version in AssemblyInfo.cs. This is the versioning formula:
|
||||
- Major.Minor.Revision.BuildDate (tick Revision if you're fixing prior to an actual planned release)
|
||||
- Do not release any development builds on the forums without consulting another developer first.
|
||||
- __Document code prior to marking it done in JIRA__
|
||||
- Move any un-tested code to the "Needs Validation" section on JIRA prior to marking it as done.
|
||||
- Do not push changes to any branch without a proper issue being assigned in JIRA. If a feature isn't planned for this release, __it shouldn't be in the repo about to be released__.
|
||||
- Submit all pull requests to the general-devel branch prior to the master branch, or you will be ignored.
|
||||
36
CONTRIBUTING.md
Normal file
36
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
### Issue Guidelines
|
||||
Please follow these simple requirements before posting an issue:
|
||||
|
||||
1. TShock version number
|
||||
2. Any stack traces that may have happened when the issue occurred
|
||||
3. How to reproduce the issue
|
||||
|
||||
### Pull Request Dev Guidelines
|
||||
|
||||
These guidelines are for contributors. If you do not follow these guidelines your commits will be reverted.
|
||||
|
||||
Required:
|
||||
- Follow the code style. We generally use microsofts except for m_ infront of private variables.
|
||||
- Do not push unfinished features to the master branch, instead create a remote branch and push to that.
|
||||
- Do not push untested code to the master branch, instead push to the test branch.
|
||||
- Document all compatibility issues in the COMPATIBILITY file. (IE file formats changing)
|
||||
- DO NOT MASS COMMIT. Commit changes as you go (without pushing). That way when you push we don't get a thousand changes with a 1-3 line commit message.
|
||||
|
||||
Optional:
|
||||
- Build Version Increment (http://autobuildversion.codeplex.com/).
|
||||
|
||||
----
|
||||
|
||||
### Dev Team Guidelines
|
||||
|
||||
These guidelines are to be followed by all developers with commit level access to this repository:
|
||||
|
||||
- Do not, for any reason, submit code to the master branch before it hits the development branch first. If the development branch is far ahead, and a new bug fix is going out, branch master, then merge with master and remove your branch.
|
||||
- If you are found to do this, you will be the person merging and rebasing your code to fit general-devel.
|
||||
- Prior to posting any version on the website, you must tick the version in AssemblyInfo.cs. This is the versioning formula:
|
||||
- Major.Minor.Revision.BuildDate (tick Revision if you're fixing prior to an actual planned release)
|
||||
- Do not release any development builds on the forums without consulting another developer first.
|
||||
- __Document code prior to marking it done in JIRA__
|
||||
- Move any un-tested code to the "Needs Validation" section on JIRA prior to marking it as done.
|
||||
- Do not push changes to any branch without a proper issue being assigned in JIRA. If a feature isn't planned for this release, __it shouldn't be in the repo about to be released__.
|
||||
- Submit all pull requests to the general-devel branch prior to the master branch, or you will be ignored.
|
||||
55
DBEditor/.gitignore
vendored
55
DBEditor/.gitignore
vendored
|
|
@ -1,55 +0,0 @@
|
|||
|
||||
# Compiled source #
|
||||
###################
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
*/bin/*
|
||||
*/obj/*
|
||||
bin/*
|
||||
obj/*
|
||||
|
||||
# Packages #
|
||||
############
|
||||
# it's better to unpack these files and commit the raw source
|
||||
# git has its own built in compression methods
|
||||
*.7z
|
||||
*.dmg
|
||||
*.gz
|
||||
*.iso
|
||||
*.jar
|
||||
*.rar
|
||||
*.tar
|
||||
*.zip
|
||||
|
||||
# Logs and databases #
|
||||
######################
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
# OS generated files #
|
||||
######################
|
||||
.DS_Store?
|
||||
ehthumbs.db
|
||||
Icon?
|
||||
Thumbs.db
|
||||
|
||||
|
||||
# Visual Studio shit Motherfucka #
|
||||
##################################
|
||||
*.suo
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.cache
|
||||
*.pdb
|
||||
*.csproj.user
|
||||
*/_ReSharper*/*
|
||||
*.user
|
||||
|
||||
#Template Bat file#
|
||||
###################
|
||||
myass.bat
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public class TShockCommandsList
|
||||
{
|
||||
public static void AddRemainingTShockCommands()
|
||||
{
|
||||
List<string> CommandList = new List<string>();
|
||||
|
||||
CommandList.Add("reservedslot");
|
||||
CommandList.Add("canwater");
|
||||
CommandList.Add("canlava");
|
||||
CommandList.Add("canbuild");
|
||||
CommandList.Add("adminchat");
|
||||
CommandList.Add("warp");
|
||||
CommandList.Add("kick");
|
||||
CommandList.Add("ban");
|
||||
CommandList.Add("unban");
|
||||
CommandList.Add("whitelist");
|
||||
CommandList.Add("maintenance");
|
||||
CommandList.Add("causeevents");
|
||||
CommandList.Add("spawnboss");
|
||||
CommandList.Add("spawnmob");
|
||||
CommandList.Add("tp");
|
||||
CommandList.Add("tphere");
|
||||
CommandList.Add("managewarp");
|
||||
CommandList.Add("editspawn");
|
||||
CommandList.Add("cfg");
|
||||
CommandList.Add("time");
|
||||
CommandList.Add("pvpfun");
|
||||
CommandList.Add("logs");
|
||||
CommandList.Add("kill");
|
||||
CommandList.Add("butcher");
|
||||
CommandList.Add("item");
|
||||
CommandList.Add("clearitems");
|
||||
CommandList.Add("heal");
|
||||
CommandList.Add("whisper");
|
||||
CommandList.Add("annoy");
|
||||
CommandList.Add("immunetokick");
|
||||
CommandList.Add("immunetoban");
|
||||
CommandList.Add("usebanneditem");
|
||||
|
||||
CommandList.Add("canregister");
|
||||
CommandList.Add("canlogin");
|
||||
CommandList.Add("canchangepassword");
|
||||
CommandList.Add("canpartychat");
|
||||
CommandList.Add("cantalkinthird");
|
||||
CommandList.Add("candisplayplaying");
|
||||
|
||||
foreach (string command in CommandList)
|
||||
{
|
||||
if (!TShockDBEditor.CommandList.Contains(command))
|
||||
TShockDBEditor.CommandList.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public static class DbExt
|
||||
{
|
||||
public static IDbDataParameter AddParameter(this IDbCommand command, string name, object data)
|
||||
{
|
||||
var parm = command.CreateParameter();
|
||||
parm.ParameterName = name;
|
||||
parm.Value = data;
|
||||
command.Parameters.Add(parm);
|
||||
return parm;
|
||||
}
|
||||
|
||||
static Dictionary<Type, Func<IDataReader, int, object>> ReadFuncs = new Dictionary<Type, Func<IDataReader, int, object>>()
|
||||
{
|
||||
{typeof(bool), (s, i) => s.GetBoolean(i)},
|
||||
{typeof(byte), (s, i) => s.GetByte(i)},
|
||||
{typeof(Int16), (s, i) => s.GetInt16(i)},
|
||||
{typeof(Int32), (s, i) => s.GetInt32(i)},
|
||||
{typeof(Int64), (s, i) => s.GetInt64(i)},
|
||||
{typeof(string), (s, i) => s.GetString(i)},
|
||||
{typeof(decimal), (s, i) => s.GetDecimal(i)},
|
||||
{typeof(float), (s, i) => s.GetFloat(i)},
|
||||
{typeof(double), (s, i) => s.GetDouble(i)},
|
||||
};
|
||||
|
||||
public static T Get<T>(this IDataReader reader, string column)
|
||||
{
|
||||
return reader.Get<T>(reader.GetOrdinal(column));
|
||||
}
|
||||
|
||||
public static T Get<T>(this IDataReader reader, int column)
|
||||
{
|
||||
if (ReadFuncs.ContainsKey(typeof(T)))
|
||||
return (T)ReadFuncs[typeof(T)](reader, column);
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public class Group
|
||||
{
|
||||
public readonly List<string> permissions = new List<string>();
|
||||
private readonly List<string> negatedpermissions = new List<string>();
|
||||
|
||||
public int ID { get; protected set; }
|
||||
public string Name { get; set; }
|
||||
public Group Parent { get; set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
public Group(int id, string groupname, int order, Group parentgroup = null)
|
||||
{
|
||||
Order = order;
|
||||
ID = id;
|
||||
Name = groupname;
|
||||
Parent = parentgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,359 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public class Itemlist
|
||||
{
|
||||
public static List<string> ItemList = new List<string>();
|
||||
|
||||
public static void AddItems()
|
||||
{
|
||||
ItemList.Add("Iron Pickaxe");
|
||||
ItemList.Add("Dirt Block");
|
||||
ItemList.Add("Stone Block");
|
||||
ItemList.Add("Iron Broadsword");
|
||||
ItemList.Add("Mushroom");
|
||||
ItemList.Add("Iron Shortsword");
|
||||
ItemList.Add("Iron Hammer");
|
||||
ItemList.Add("Torch");
|
||||
ItemList.Add("Wood");
|
||||
ItemList.Add("Iron Axe");
|
||||
ItemList.Add("Iron Ore");
|
||||
ItemList.Add("Copper Ore");
|
||||
ItemList.Add("Gold Ore");
|
||||
ItemList.Add("Silver Ore");
|
||||
ItemList.Add("Copper Watch");
|
||||
ItemList.Add("Silver Watch");
|
||||
ItemList.Add("Gold Watch");
|
||||
ItemList.Add("Depth Meter");
|
||||
ItemList.Add("Gold Bar");
|
||||
ItemList.Add("Copper Bar");
|
||||
ItemList.Add("Silver Bar");
|
||||
ItemList.Add("Iron Bar");
|
||||
ItemList.Add("Gel");
|
||||
ItemList.Add("Wooden Sword");
|
||||
ItemList.Add("Wooden Door");
|
||||
ItemList.Add("Stone Wall");
|
||||
ItemList.Add("Acorn");
|
||||
ItemList.Add("Lesser Healing Potion");
|
||||
ItemList.Add("Life Crystal");
|
||||
ItemList.Add("Dirt Wall");
|
||||
ItemList.Add("Bottle");
|
||||
ItemList.Add("Wooden Table");
|
||||
ItemList.Add("Furnace");
|
||||
ItemList.Add("Wooden Chair");
|
||||
ItemList.Add("Iron Anvil");
|
||||
ItemList.Add("Work Bench");
|
||||
ItemList.Add("Goggles");
|
||||
ItemList.Add("Lens");
|
||||
ItemList.Add("Wooden Bow");
|
||||
ItemList.Add("Wooden Arrow");
|
||||
ItemList.Add("Flaming Arrow");
|
||||
ItemList.Add("Shuriken");
|
||||
ItemList.Add("Suspicious Looking Eye");
|
||||
ItemList.Add("Demon Bow");
|
||||
ItemList.Add("War Axe of the Night");
|
||||
ItemList.Add("Light's Bane");
|
||||
ItemList.Add("Unholy Arrow");
|
||||
ItemList.Add("Chest");
|
||||
ItemList.Add("Band of Regeneration");
|
||||
ItemList.Add("Magic Mirror");
|
||||
ItemList.Add("Jester's Arrow");
|
||||
ItemList.Add("Angel Statue");
|
||||
ItemList.Add("Cloud in a Bottle");
|
||||
ItemList.Add("Hermes Boots");
|
||||
ItemList.Add("Enchanted Boomerang");
|
||||
ItemList.Add("Demonite Ore");
|
||||
ItemList.Add("Demonite Bar");
|
||||
ItemList.Add("Heart");
|
||||
ItemList.Add("Corrupt Seeds");
|
||||
ItemList.Add("Vile Mushroom");
|
||||
ItemList.Add("Ebonstone Block");
|
||||
ItemList.Add("Grass Seeds");
|
||||
ItemList.Add("Sunflower");
|
||||
ItemList.Add("Vilethorn");
|
||||
ItemList.Add("Starfury");
|
||||
ItemList.Add("Purification Powder");
|
||||
ItemList.Add("Vile Powder");
|
||||
ItemList.Add("Rotten Chunk");
|
||||
ItemList.Add("Worm Tooth");
|
||||
ItemList.Add("Worm Food");
|
||||
ItemList.Add("Copper Coin");
|
||||
ItemList.Add("Silver Coin");
|
||||
ItemList.Add("Gold Coin");
|
||||
ItemList.Add("Platinum Coin");
|
||||
ItemList.Add("Fallen Star");
|
||||
ItemList.Add("Copper Greaves");
|
||||
ItemList.Add("Iron Greaves");
|
||||
ItemList.Add("Silver Greaves");
|
||||
ItemList.Add("Gold Greaves");
|
||||
ItemList.Add("Copper Chainmail");
|
||||
ItemList.Add("Iron Chainmail");
|
||||
ItemList.Add("Silver Chainmail");
|
||||
ItemList.Add("Gold Chainmail");
|
||||
ItemList.Add("Grappling Hook");
|
||||
ItemList.Add("Iron Chain");
|
||||
ItemList.Add("Shadow Scale");
|
||||
ItemList.Add("Piggy Bank");
|
||||
ItemList.Add("Mining Helmet");
|
||||
ItemList.Add("Copper Helmet");
|
||||
ItemList.Add("Iron Helmet");
|
||||
ItemList.Add("Silver Helmet");
|
||||
ItemList.Add("Gold Helmet");
|
||||
ItemList.Add("Wood Wall");
|
||||
ItemList.Add("Wood Platform");
|
||||
ItemList.Add("Flintlock Pistol");
|
||||
ItemList.Add("Musket");
|
||||
ItemList.Add("Musket Ball");
|
||||
ItemList.Add("Minishark");
|
||||
ItemList.Add("Iron Bow");
|
||||
ItemList.Add("Shadow Greaves");
|
||||
ItemList.Add("Shadow Scalemail");
|
||||
ItemList.Add("Shadow Helmet");
|
||||
ItemList.Add("Nightmare Pickaxe");
|
||||
ItemList.Add("The Breaker");
|
||||
ItemList.Add("Candle");
|
||||
ItemList.Add("Copper Chandelier");
|
||||
ItemList.Add("Silver Chandelier");
|
||||
ItemList.Add("Gold Chandelier");
|
||||
ItemList.Add("Mana Crystal");
|
||||
ItemList.Add("Lesser Mana Potion");
|
||||
ItemList.Add("Band of Starpower");
|
||||
ItemList.Add("Flower of Fire");
|
||||
ItemList.Add("Magic Missile");
|
||||
ItemList.Add("Dirt Rod");
|
||||
ItemList.Add("Orb of Light");
|
||||
ItemList.Add("Meteorite");
|
||||
ItemList.Add("Meteorite Bar");
|
||||
ItemList.Add("Hook");
|
||||
ItemList.Add("Flamarang");
|
||||
ItemList.Add("Molten Fury");
|
||||
ItemList.Add("Fiery Greatsword");
|
||||
ItemList.Add("Molten Pickaxe");
|
||||
ItemList.Add("Meteor Helmet");
|
||||
ItemList.Add("Meteor Suit");
|
||||
ItemList.Add("Meteor Leggings");
|
||||
ItemList.Add("Bottled Water");
|
||||
ItemList.Add("Space Gun");
|
||||
ItemList.Add("Rocket Boots");
|
||||
ItemList.Add("Gray Brick");
|
||||
ItemList.Add("Gray Brick Wall");
|
||||
ItemList.Add("Red Brick");
|
||||
ItemList.Add("Red Brick Wall");
|
||||
ItemList.Add("Clay Block");
|
||||
ItemList.Add("Blue Brick");
|
||||
ItemList.Add("Blue Brick Wall");
|
||||
ItemList.Add("Chain Lantern");
|
||||
ItemList.Add("Green Brick");
|
||||
ItemList.Add("Green Brick Wall");
|
||||
ItemList.Add("Pink Brick");
|
||||
ItemList.Add("Pink Brick Wall");
|
||||
ItemList.Add("Gold Brick");
|
||||
ItemList.Add("Gold Brick Wall");
|
||||
ItemList.Add("Silver Brick");
|
||||
ItemList.Add("Silver Brick Wall");
|
||||
ItemList.Add("Copper Brick");
|
||||
ItemList.Add("Copper Brick Wall");
|
||||
ItemList.Add("Spike");
|
||||
ItemList.Add("Water Candle");
|
||||
ItemList.Add("Book");
|
||||
ItemList.Add("Cobweb");
|
||||
ItemList.Add("Necro Helmet");
|
||||
ItemList.Add("Necro Breastplate");
|
||||
ItemList.Add("Necro Greaves");
|
||||
ItemList.Add("Bone");
|
||||
ItemList.Add("Muramasa");
|
||||
ItemList.Add("Cobalt Shield");
|
||||
ItemList.Add("Aqua Scepter");
|
||||
ItemList.Add("Lucky Horseshoe");
|
||||
ItemList.Add("Shiny Red Balloon");
|
||||
ItemList.Add("Harpoon");
|
||||
ItemList.Add("Spiky Ball");
|
||||
ItemList.Add("Ball 'O Hurt");
|
||||
ItemList.Add("Blue Moon");
|
||||
ItemList.Add("Handgun");
|
||||
ItemList.Add("Water Bolt");
|
||||
ItemList.Add("Bomb");
|
||||
ItemList.Add("Dynamite");
|
||||
ItemList.Add("Grenade");
|
||||
ItemList.Add("Sand Block");
|
||||
ItemList.Add("Glass");
|
||||
ItemList.Add("Sign");
|
||||
ItemList.Add("Ash Block");
|
||||
ItemList.Add("Obsidian");
|
||||
ItemList.Add("Hellstone");
|
||||
ItemList.Add("Hellstone Bar");
|
||||
ItemList.Add("Mud Block");
|
||||
ItemList.Add("Sapphire");
|
||||
ItemList.Add("Ruby");
|
||||
ItemList.Add("Emerald");
|
||||
ItemList.Add("Topaz");
|
||||
ItemList.Add("Amethyst");
|
||||
ItemList.Add("Diamond");
|
||||
ItemList.Add("Glowing Mushroom");
|
||||
ItemList.Add("Star");
|
||||
ItemList.Add("Ivy Whip");
|
||||
ItemList.Add("Breathing Reed");
|
||||
ItemList.Add("Flipper");
|
||||
ItemList.Add("Healing Potion");
|
||||
ItemList.Add("Mana Potion");
|
||||
ItemList.Add("Blade of Grass");
|
||||
ItemList.Add("Thorn Chakrum");
|
||||
ItemList.Add("Obsidian Brick");
|
||||
ItemList.Add("Obsidian Skull");
|
||||
ItemList.Add("Mushroom Grass Seeds");
|
||||
ItemList.Add("Jungle Grass Seeds");
|
||||
ItemList.Add("Wooden Hammer");
|
||||
ItemList.Add("Star Cannon");
|
||||
ItemList.Add("Blue Phaseblade");
|
||||
ItemList.Add("Red Phaseblade");
|
||||
ItemList.Add("Green Phaseblade");
|
||||
ItemList.Add("Purple Phaseblade");
|
||||
ItemList.Add("White Phaseblade");
|
||||
ItemList.Add("Yellow Phaseblade");
|
||||
ItemList.Add("Meteor Hamaxe");
|
||||
ItemList.Add("Empty Bucket");
|
||||
ItemList.Add("Water Bucket");
|
||||
ItemList.Add("Lava Bucket");
|
||||
ItemList.Add("Jungle Rose");
|
||||
ItemList.Add("Stinger");
|
||||
ItemList.Add("Vine");
|
||||
ItemList.Add("Feral Claws");
|
||||
ItemList.Add("Anklet of the Wind");
|
||||
ItemList.Add("Staff of Regrowth");
|
||||
ItemList.Add("Hellstone Brick");
|
||||
ItemList.Add("Whoopie Cushion");
|
||||
ItemList.Add("Shackle");
|
||||
ItemList.Add("Molten Hamaxe");
|
||||
ItemList.Add("Flamelash");
|
||||
ItemList.Add("Phoenix Blaster");
|
||||
ItemList.Add("Sunfury");
|
||||
ItemList.Add("Hellforge");
|
||||
ItemList.Add("Clay Pot");
|
||||
ItemList.Add("Nature's Gift");
|
||||
ItemList.Add("Bed");
|
||||
ItemList.Add("Silk");
|
||||
ItemList.Add("Lesser Restoration Potion");
|
||||
ItemList.Add("Restoration Potion");
|
||||
ItemList.Add("Jungle Hat");
|
||||
ItemList.Add("Jungle Shirt");
|
||||
ItemList.Add("Jungle Pants");
|
||||
ItemList.Add("Molten Helmet");
|
||||
ItemList.Add("Molten Breastplate");
|
||||
ItemList.Add("Molten Greaves");
|
||||
ItemList.Add("Meteor Shot");
|
||||
ItemList.Add("Sticky Bomb");
|
||||
ItemList.Add("Black Lens");
|
||||
ItemList.Add("Sunglasses");
|
||||
ItemList.Add("Wizard Hat");
|
||||
ItemList.Add("Top Hat");
|
||||
ItemList.Add("Tuxedo Shirt");
|
||||
ItemList.Add("Tuxedo Pants");
|
||||
ItemList.Add("Summer Hat");
|
||||
ItemList.Add("Bunny Hood");
|
||||
ItemList.Add("Plumber's Hat");
|
||||
ItemList.Add("Plumber's Shirt");
|
||||
ItemList.Add("Plumber's Pants");
|
||||
ItemList.Add("Hero's Hat");
|
||||
ItemList.Add("Hero's Shirt");
|
||||
ItemList.Add("Hero's Pants");
|
||||
ItemList.Add("Fish Bowl");
|
||||
ItemList.Add("Archaeologist's Hat");
|
||||
ItemList.Add("Archaeologist's Jacket");
|
||||
ItemList.Add("Archaeologist's Pants");
|
||||
ItemList.Add("Black Dye");
|
||||
ItemList.Add("Green Dye");
|
||||
ItemList.Add("Ninja Hood");
|
||||
ItemList.Add("Ninja Shirt");
|
||||
ItemList.Add("Ninja Pants");
|
||||
ItemList.Add("Leather");
|
||||
ItemList.Add("Red Hat");
|
||||
ItemList.Add("Goldfish");
|
||||
ItemList.Add("Robe");
|
||||
ItemList.Add("Robot Hat");
|
||||
ItemList.Add("Gold Crown");
|
||||
ItemList.Add("Hellfire Arrow");
|
||||
ItemList.Add("Sandgun");
|
||||
ItemList.Add("Guide Voodoo Doll");
|
||||
ItemList.Add("Diving Helmet");
|
||||
ItemList.Add("Familiar Shirt");
|
||||
ItemList.Add("Familiar Pants");
|
||||
ItemList.Add("Familiar Wig");
|
||||
ItemList.Add("Demon Scythe");
|
||||
ItemList.Add("Night's Edge");
|
||||
ItemList.Add("Dark Lance");
|
||||
ItemList.Add("Coral");
|
||||
ItemList.Add("Cactus");
|
||||
ItemList.Add("Trident");
|
||||
ItemList.Add("Silver Bullet");
|
||||
ItemList.Add("Throwing Knife");
|
||||
ItemList.Add("Spear");
|
||||
ItemList.Add("Blowpipe");
|
||||
ItemList.Add("Glowstick");
|
||||
ItemList.Add("Seed");
|
||||
ItemList.Add("Wooden Boomerang");
|
||||
ItemList.Add("Aglet");
|
||||
ItemList.Add("Sticky Glowstick");
|
||||
ItemList.Add("Poisoned Knife");
|
||||
ItemList.Add("Obsidian Skin Potion");
|
||||
ItemList.Add("Regeneration Potion");
|
||||
ItemList.Add("Swiftness Potion");
|
||||
ItemList.Add("Gills potion");
|
||||
ItemList.Add("Ironskin Potion");
|
||||
ItemList.Add("Mana Regeneration Potion");
|
||||
ItemList.Add("Magic Power Potion");
|
||||
ItemList.Add("Featherfall Potion");
|
||||
ItemList.Add("Spelunker Potion");
|
||||
ItemList.Add("Invisibility Potion");
|
||||
ItemList.Add("Shine Potion");
|
||||
ItemList.Add("Night Owl Potion");
|
||||
ItemList.Add("Battle Potion");
|
||||
ItemList.Add("Thorns Potion");
|
||||
ItemList.Add("Water Walking Potion");
|
||||
ItemList.Add("Archery Potion");
|
||||
ItemList.Add("Hunter Potion");
|
||||
ItemList.Add("Gravitation Potion");
|
||||
ItemList.Add("Gold Chest");
|
||||
ItemList.Add("Daybloom Seeds");
|
||||
ItemList.Add("Moonglow Seeds");
|
||||
ItemList.Add("Blinkroot Seeds");
|
||||
ItemList.Add("Deathweed Seeds");
|
||||
ItemList.Add("Waterleaf Seeds");
|
||||
ItemList.Add("Fireblossom Seeds");
|
||||
ItemList.Add("Daybloom");
|
||||
ItemList.Add("Moonglow");
|
||||
ItemList.Add("Blinkroot");
|
||||
ItemList.Add("Deathweed");
|
||||
ItemList.Add("Waterleaf");
|
||||
ItemList.Add("Fireblossom");
|
||||
ItemList.Add("Shark Fin");
|
||||
ItemList.Add("Feather");
|
||||
ItemList.Add("Tombstone");
|
||||
ItemList.Add("Mime Mask");
|
||||
ItemList.Add("Antlion Mandible");
|
||||
ItemList.Add("Illegal Gun Parts");
|
||||
ItemList.Add("The Doctor's Shirt");
|
||||
ItemList.Add("The Doctor's Pants");
|
||||
}
|
||||
}
|
||||
}
|
||||
1152
DBEditor/Main.Designer.cs
generated
1152
DBEditor/Main.Designer.cs
generated
File diff suppressed because it is too large
Load diff
777
DBEditor/Main.cs
777
DBEditor/Main.cs
|
|
@ -1,777 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using Mono.Data.Sqlite;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace TShockDBEditor
|
||||
{
|
||||
public partial class TShockDBEditor : Form
|
||||
{
|
||||
public OpenFileDialog dialog = new OpenFileDialog();
|
||||
public List<Group> groups = new List<Group>();
|
||||
public static List<string> CommandList = new List<string>();
|
||||
public IDbConnection DB;
|
||||
public string dbtype = "";
|
||||
|
||||
public TShockDBEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
Itemlist.AddItems();
|
||||
dialog.FileOk += new CancelEventHandler(dialog_FileOk);
|
||||
dialog.Filter = "SQLite Database (*.sqlite)|*.sqlite";
|
||||
}
|
||||
|
||||
public void LoadDB()
|
||||
{
|
||||
|
||||
itemListBanned.Items.Clear();
|
||||
lst_groupList.Items.Clear();
|
||||
lst_AvailableCmds.Items.Clear();
|
||||
lst_bannedCmds.Items.Clear();
|
||||
itemListAvailable.Items.Clear();
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Itembans";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
itemListBanned.Items.Add(reader.Get<string>("ItemName"));
|
||||
}
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM GroupList";
|
||||
|
||||
lst_groupList.Items.Add("superadmin");
|
||||
lst_usergrplist.Items.Add("superadmin");
|
||||
lst_newusergrplist.Items.Add("superadmin");
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
lst_groupList.Items.Add(reader.Get<string>("GroupName"));
|
||||
lst_inheritgrps.Items.Add(reader.Get<string>("GroupName"));
|
||||
lst_usergrplist.Items.Add(reader.Get<string>("GroupName"));
|
||||
lst_newusergrplist.Items.Add(reader.Get<string>("GroupName"));
|
||||
}
|
||||
}
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
foreach (string command in reader.Get<string>("Commands").Split(','))
|
||||
{
|
||||
if (!lst_groupList.Items.Contains(command))
|
||||
if (!CommandList.Contains(command))
|
||||
CommandList.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TShockCommandsList.AddRemainingTShockCommands();
|
||||
}
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Users";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.Get<string>("UserName") != "")
|
||||
lst_userlist.Items.Add(reader.Get<string>("UserName"));
|
||||
else
|
||||
lst_userlist.Items.Add(reader.Get<string>("IP"));
|
||||
}
|
||||
}
|
||||
}
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Bans";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
lst_bans.Items.Add(reader.Get<string>("Name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Itemlist.ItemList.Count; i++)
|
||||
{
|
||||
if (!itemListBanned.Items.Contains(Itemlist.ItemList[i]))
|
||||
itemListAvailable.Items.Add(Itemlist.ItemList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadSqliteDatabase(string path)
|
||||
{
|
||||
string sql = dialog.FileName;
|
||||
DB = new SqliteConnection(string.Format("uri=file://{0},Version=3", sql));
|
||||
DB.Open();
|
||||
dbtype = "sqlite";
|
||||
LoadDB();
|
||||
}
|
||||
|
||||
public void LoadMySqlDatabase(string hostname = "localhost", string port = "3306", string database = "", string dbusername = "", string dbpassword = "")
|
||||
{
|
||||
DB = new MySqlConnection();
|
||||
DB.ConnectionString =
|
||||
"Server='" + hostname +
|
||||
"';Port='" + port +
|
||||
"';Database='" + database +
|
||||
"';Uid='" + dbusername +
|
||||
"';Pwd='" + dbpassword + "';";
|
||||
DB.Open();
|
||||
dbtype = "mysql";
|
||||
LoadDB();
|
||||
}
|
||||
|
||||
#region BannedItemsTab
|
||||
public void btn_moveAllRightItems_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (object item in itemListAvailable.Items)
|
||||
{
|
||||
itemListBanned.Items.Add(item);
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO ItemBans (ItemName) VALUES (@itemname);";
|
||||
com.AddParameter("@itemname", item.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
itemListAvailable.Items.Clear();
|
||||
}
|
||||
|
||||
private void btn_moveAllLeftItems_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach (object item in itemListBanned.Items)
|
||||
{
|
||||
itemListAvailable.Items.Add(item);
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM ItemBans WHERE ItemName=@itemname;";
|
||||
com.AddParameter("@itemname", item.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
itemListBanned.Items.Clear();
|
||||
}
|
||||
|
||||
private void btn_moveRightItems_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (itemListAvailable.SelectedItem != null)
|
||||
{
|
||||
itemListBanned.Items.Add(itemListAvailable.SelectedItem);
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO ItemBans (ItemName) VALUES (@itemname);";
|
||||
com.AddParameter("@itemname", itemListAvailable.SelectedItem.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
itemListAvailable.Items.Remove(itemListAvailable.SelectedItem);
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_moveLeftItems_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (itemListBanned.SelectedItem != null)
|
||||
{
|
||||
itemListAvailable.Items.Add(itemListBanned.SelectedItem);
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM ItemBans WHERE ItemName=@itemname;";
|
||||
com.AddParameter("@itemname", itemListBanned.SelectedItem.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
itemListBanned.Items.Remove(itemListBanned.SelectedItem);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GroupTab
|
||||
|
||||
private void lst_groupList_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if ((string)lst_groupList.SelectedItem != "superadmin")
|
||||
UpdateGroupIndex(lst_groupList.SelectedIndex);
|
||||
else
|
||||
lst_groupList.SelectedIndex = -1;
|
||||
}
|
||||
|
||||
private void UpdateGroupIndex(int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
lst_AvailableCmds.Items.Clear();
|
||||
lst_bannedCmds.Items.Clear();
|
||||
|
||||
com.CommandText =
|
||||
"SELECT * FROM GroupList WHERE GroupName=@groupname";
|
||||
com.AddParameter("@groupname", lst_groupList.Items[index].ToString());
|
||||
|
||||
lbl_grpchild.Text = "";
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
foreach (string command in reader.Get<string>("Commands").Split(','))
|
||||
{
|
||||
if (lst_groupList.Items.Contains(command) || command == "")
|
||||
lbl_grpchild.Text = command;
|
||||
else
|
||||
lst_AvailableCmds.Items.Add(command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lbl_grpchild.Text == "")
|
||||
lbl_grpchild.Text = "none";
|
||||
|
||||
for (int i = 0; i < CommandList.Count; i++)
|
||||
{
|
||||
if (!lst_AvailableCmds.Items.Contains(CommandList[i]))
|
||||
lst_bannedCmds.Items.Add(CommandList[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_moveAllRightCmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (object cmd in lst_bannedCmds.Items)
|
||||
{
|
||||
lst_AvailableCmds.Items.Add(cmd);
|
||||
|
||||
if (string.IsNullOrEmpty(sb.ToString()))
|
||||
sb.Append(cmd.ToString());
|
||||
else
|
||||
sb.Append(",").Append(cmd.ToString());
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@cmds WHERE GroupName=@name;";
|
||||
com.AddParameter("@name", lst_groupList.Items[lst_groupList.SelectedIndex].ToString());
|
||||
com.AddParameter("@cmds", sb.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
lst_bannedCmds.Items.Clear();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_moveRightCmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
lst_AvailableCmds.Items.Add(lst_bannedCmds.Items[lst_bannedCmds.SelectedIndex]);
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (object cmd in lst_AvailableCmds.Items)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sb.ToString()))
|
||||
sb.Append(cmd.ToString());
|
||||
else
|
||||
sb.Append(",").Append(cmd.ToString());
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@cmds WHERE GroupName=@name;";
|
||||
com.AddParameter("@name", lst_groupList.Items[lst_groupList.SelectedIndex].ToString());
|
||||
com.AddParameter("@cmds", sb.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
lst_bannedCmds.Items.Remove(lst_bannedCmds.Items[lst_bannedCmds.SelectedIndex]);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_moveLeftCmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
lst_bannedCmds.Items.Add(lst_AvailableCmds.Items[lst_AvailableCmds.SelectedIndex]);
|
||||
lst_AvailableCmds.Items.Remove(lst_AvailableCmds.Items[lst_AvailableCmds.SelectedIndex]);
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (object cmd in lst_AvailableCmds.Items)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sb.ToString()))
|
||||
sb.Append(cmd.ToString());
|
||||
else
|
||||
sb.Append(",").Append(cmd.ToString());
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@cmds WHERE GroupName=@name;";
|
||||
com.AddParameter("@name", lst_groupList.Items[lst_groupList.SelectedIndex].ToString());
|
||||
com.AddParameter("@cmds", sb.ToString());
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_moveAllLeftCmd_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (object cmd in lst_AvailableCmds.Items)
|
||||
{
|
||||
lst_bannedCmds.Items.Add(cmd);
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "UPDATE GroupList SET Commands=@cmds WHERE GroupName=@name;";
|
||||
com.AddParameter("@name", lst_groupList.Items[lst_groupList.SelectedIndex].ToString());
|
||||
com.AddParameter("@cmds", "");
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
lst_AvailableCmds.Items.Clear();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_newgroup_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (txt_grpname.Text != "")
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
if (dbtype == "sqlite")
|
||||
com.CommandText = "INSERT OR IGNORE INTO GroupList (GroupName, Commands) VALUES (@groupname, @commands);";
|
||||
else if (dbtype == "mysql")
|
||||
com.CommandText = "INSERT IGNORE INTO GroupList SET GroupName=@groupname, Commands=@commands;";
|
||||
com.AddParameter("@groupname", txt_grpname.Text);
|
||||
|
||||
if (lst_inheritgrps.SelectedIndex > -1)
|
||||
com.AddParameter("@commands", lst_inheritgrps.Items[lst_inheritgrps.SelectedIndex]);
|
||||
else
|
||||
com.AddParameter("@commands", "");
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected > 0)
|
||||
{
|
||||
lst_groupList.Items.Add(txt_grpname.Text);
|
||||
lst_inheritgrps.Items.Add(txt_grpname.Text);
|
||||
lst_usergrplist.Items.Add(txt_grpname.Text);
|
||||
txt_grpname.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
com.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private void btn_deletegroup_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "DELETE FROM Grouplist WHERE GroupName = @groupname";
|
||||
com.AddParameter("@groupname", lst_groupList.Items[lst_groupList.SelectedIndex]);
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
lst_groupList.Items.Remove(lst_groupList.Items[lst_groupList.SelectedIndex]);
|
||||
|
||||
lst_inheritgrps.Items.Clear();
|
||||
lst_usergrplist.Items.Clear();
|
||||
com.CommandText =
|
||||
"SELECT * FROM GroupList";
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
lst_inheritgrps.Items.Add(reader.Get<string>("GroupName"));
|
||||
lst_usergrplist.Items.Add(reader.Get<string>("GroupName"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region FileOpenTabs
|
||||
|
||||
private void btn_OpenLocalDB_Click(object sender, EventArgs e)
|
||||
{
|
||||
dialog.ShowDialog();
|
||||
}
|
||||
|
||||
void dialog_FileOk(object sender, CancelEventArgs e)
|
||||
{
|
||||
LoadSqliteDatabase(dialog.FileName);
|
||||
tabControl.Visible = true;
|
||||
}
|
||||
|
||||
private void btn_connect_Click(object sender, EventArgs e)
|
||||
{
|
||||
LoadMySqlDatabase(txt_hostname.Text, txt_port.Text, txt_dbname.Text, txt_dbusername.Text, txt_dbpassword.Text);
|
||||
tabControl.Visible = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BansTab
|
||||
|
||||
private void lst_bans_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
if (lst_bans.SelectedIndex > -1)
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Bans WHERE Name=@name";
|
||||
com.AddParameter("@name", lst_bans.Items[lst_bans.SelectedIndex]);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
txt_banip.Text = reader.Get<string>("IP");
|
||||
txt_banname.Text = reader.Get<string>("Name");
|
||||
txt_banreason.Text = reader.Get<string>("Reason");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_bandelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"DELETE FROM Bans WHERE IP=@ip";
|
||||
com.AddParameter("@ip", txt_banip.Text);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected > 0)
|
||||
{
|
||||
txt_banip.Text = "";
|
||||
txt_banname.Text = "";
|
||||
txt_banreason.Text = "";
|
||||
lst_bans.Items.Remove(lst_bans.Items[lst_bans.SelectedIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_bannew_Click(object sender, EventArgs e)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
if (dbtype == "sqlite")
|
||||
com.CommandText = "INSERT INTO Bans (IP, Name, Reason) VALUES (@ip, @name, @reason);";
|
||||
else if (dbtype == "mysql")
|
||||
com.CommandText = "INSERT INTO Bans SET IP=@ip, Name=@name, Reason=@reason;";
|
||||
if (txt_newbanip.Text != "" && txt_newbanname.Text != "")
|
||||
{
|
||||
com.AddParameter("@ip", txt_newbanip.Text);
|
||||
com.AddParameter("@name", txt_newbanname.Text);
|
||||
com.AddParameter("@reason", txt_newbanreason.Text);
|
||||
com.ExecuteNonQuery();
|
||||
|
||||
lst_bans.Items.Add(txt_newbanname.Text);
|
||||
txt_newbanip.Text = "";
|
||||
txt_newbanname.Text = "";
|
||||
txt_newbanreason.Text = "";
|
||||
lbl_newbanstatus.Text = "Ban added successfully!";
|
||||
}
|
||||
else
|
||||
lbl_newbanstatus.Text = "Required field('s) empty";
|
||||
|
||||
lst_bans.Items.Add(txt_newbanname.Text);
|
||||
txt_newbanip.Text = "";
|
||||
txt_newbanname.Text = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void txt_banreason_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (txt_banip.Text != "")
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"UPDATE Bans SET Reason=@reason WHERE IP=@ip";
|
||||
com.AddParameter("@reason", txt_banreason.Text);
|
||||
com.AddParameter("@ip", txt_banip.Text);
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UserTab
|
||||
|
||||
private void lst_userlist_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
txt_username.Text = "None Selected";
|
||||
txt_userip.Text = "None Selected";
|
||||
lst_usergrplist.SelectedIndex = -1;
|
||||
bool flag = false;
|
||||
|
||||
|
||||
if (lst_userlist.SelectedIndex > -1)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Users WHERE Username=@name";
|
||||
com.AddParameter("@name", lst_userlist.Items[lst_userlist.SelectedIndex]);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
txt_username.Text = reader.Get<string>("Username");
|
||||
|
||||
if (reader.Get<string>("IP") != "")
|
||||
txt_userip.Text = reader.Get<string>("IP");
|
||||
else
|
||||
txt_userip.Text = "User does not have IP";
|
||||
|
||||
if (reader.Get<string>("Password") != "")
|
||||
txt_userpass.Text = reader.Get<string>("Password");
|
||||
else
|
||||
txt_userpass.Text = "User does not have Pasword";
|
||||
|
||||
foreach (string name in lst_usergrplist.Items)
|
||||
{
|
||||
if (name == reader.Get<string>("Usergroup"))
|
||||
{
|
||||
lst_usergrplist.SelectedItem = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"SELECT * FROM Users WHERE IP=@ip";
|
||||
com.AddParameter("@ip", lst_userlist.Items[lst_userlist.SelectedIndex]);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
if (reader.Get<string>("Password") != "")
|
||||
txt_userpass.Text = reader.Get<string>("Password");
|
||||
else
|
||||
txt_userpass.Text = "User does not have Pasword";
|
||||
|
||||
txt_userip.Text = lst_userlist.Items[lst_userlist.SelectedIndex].ToString();
|
||||
|
||||
foreach (string name in lst_usergrplist.Items)
|
||||
{
|
||||
if (name == reader.Get<string>("Usergroup"))
|
||||
{
|
||||
lst_usergrplist.SelectedItem = name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void lst_usergrplist_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lst_userlist.SelectedIndex > -1)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"UPDATE Users SET Usergroup=@group WHERE Username=@user OR IP=@ip";
|
||||
com.AddParameter("@group", lst_usergrplist.SelectedItem);
|
||||
com.AddParameter("@user", txt_username.Text);
|
||||
com.AddParameter("@ip", txt_userip.Text);
|
||||
com.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_deluser_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (lst_userlist.SelectedIndex > -1)
|
||||
{
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText =
|
||||
"DELETE FROM Users WHERE IP=@ip OR Username=@user";
|
||||
com.AddParameter("@user", txt_username.Text);
|
||||
com.AddParameter("@ip", txt_userip.Text);
|
||||
com.ExecuteNonQuery();
|
||||
lst_userlist.Items.Remove(lst_userlist.SelectedItem);
|
||||
txt_userip.Text = "";
|
||||
txt_username.Text = "";
|
||||
txt_userpass.Text = "";
|
||||
lst_usergrplist.SelectedIndex = -1;
|
||||
lst_userlist.SelectedIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btn_adduser_Click(object sender, EventArgs e)
|
||||
{
|
||||
lbl_useraddstatus.Visible = true;
|
||||
|
||||
for (int i = 0; i == 0; i++)
|
||||
{
|
||||
|
||||
if ((txt_newusername.Text == "" && txt_newuserpass.Text != ""))
|
||||
{
|
||||
lbl_useraddstatus.Text = "Username field cannot be empty";
|
||||
break;
|
||||
}
|
||||
|
||||
if ((txt_newusername.Text != "" && txt_newuserpass.Text == ""))
|
||||
{
|
||||
lbl_useraddstatus.Text = "Password field cannot be empty";
|
||||
break;
|
||||
}
|
||||
|
||||
if (txt_newuserip.Text == "" && (txt_newusername.Text == "" || txt_newuserpass.Text == ""))
|
||||
{
|
||||
lbl_useraddstatus.Text = "IP field cannot be empty";
|
||||
break;
|
||||
}
|
||||
|
||||
if (lst_newusergrplist.SelectedIndex == -1)
|
||||
{
|
||||
lbl_useraddstatus.Text = "Group must be selected";
|
||||
break;
|
||||
}
|
||||
|
||||
using (var com = DB.CreateCommand())
|
||||
{
|
||||
com.CommandText = "INSERT INTO Users (Username, Password, UserGroup, IP) VALUES (@name, @password, @group, @ip);";
|
||||
com.AddParameter("@name", txt_newusername.Text);
|
||||
com.AddParameter("@password", HashPassword(txt_newuserpass.Text));
|
||||
|
||||
com.AddParameter("@group", lst_newusergrplist.SelectedItem);
|
||||
com.AddParameter("@ip", txt_newuserip.Text);
|
||||
|
||||
using (var reader = com.ExecuteReader())
|
||||
{
|
||||
if (reader.RecordsAffected > 0)
|
||||
{
|
||||
if (txt_newusername.Text != "")
|
||||
lst_userlist.Items.Add(txt_newusername.Text);
|
||||
else
|
||||
lst_userlist.Items.Add(txt_newuserip.Text);
|
||||
|
||||
txt_newuserip.Text = "";
|
||||
txt_newusername.Text = "";
|
||||
txt_newuserpass.Text = "";
|
||||
lst_newusergrplist.SelectedIndex = -1;
|
||||
|
||||
lbl_useraddstatus.Text = "User added successfully!";
|
||||
}
|
||||
else
|
||||
lbl_useraddstatus.Text = "SQL error while adding user";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static string HashPassword(string password)
|
||||
{
|
||||
using (var sha = new SHA512CryptoServiceProvider())
|
||||
{
|
||||
if (password == "")
|
||||
{
|
||||
return "nonexistent-password";
|
||||
}
|
||||
var bytes = sha.ComputeHash(Encoding.ASCII.GetBytes(password));
|
||||
return bytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void TShockDBEditor_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("WindowsFormsApplication2")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("WindowsFormsApplication2")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ffdb92d1-7f89-4f59-a671-22ea6cda680c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
81
DBEditor/Properties/Resources.Designer.cs
generated
81
DBEditor/Properties/Resources.Designer.cs
generated
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TShockDBEditor.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TShockDBEditor.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
44
DBEditor/Properties/Settings.Designer.cs
generated
44
DBEditor/Properties/Settings.Designer.cs
generated
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.1
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TShockDBEditor.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>TShockDBEditor</RootNamespace>
|
||||
<AssemblyName>TShockDBEditor</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Mono.Data.Sqlite">
|
||||
<HintPath>..\SqlBins\Mono.Data.Sqlite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Web, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Web.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CommandList.cs" />
|
||||
<Compile Include="Group.cs" />
|
||||
<Compile Include="DbExt.cs" />
|
||||
<Compile Include="Main.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Main.Designer.cs">
|
||||
<DependentUpon>Main.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Itemlist.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="Main.resx">
|
||||
<DependentUpon>Main.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>True</DesignTime>
|
||||
</Compile>
|
||||
<None Include="app.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
<None Include="TShockDBEditor.licenseheader" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<WCFMetadata Include="Service References\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
extensions: .cs
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
|
||||
74
README.md
74
README.md
|
|
@ -1,63 +1,27 @@
|
|||
TShock is a server modification for Terraria.
|
||||
# TShock [](https://travis-ci.org/NyxStudios/TShock)
|
||||
|
||||
__Continuous Integration__: http://ci.tshock.co/
|
||||
TShock is a server modification for Terraria, written in C#, and based upon the [Terraria Server API](https://github.com/Deathmax/TerrariaAPI-Server). It uses JSON for configuration management, and offers several features not present in the Terraria Server normally.
|
||||
|
||||
__Support Forums__: http://tshock.co/
|
||||
## Features
|
||||
|
||||
__Wiki__: http://ci.tshock.co:8080/
|
||||
* MySQL support
|
||||
* Permissions
|
||||
* Multiple administrators
|
||||
* Anti-cheat
|
||||
* User registration
|
||||
* Reserved slots
|
||||
* User punishment (kicking, banning, muting)
|
||||
|
||||
----
|
||||
## Community
|
||||
|
||||
### Helping out
|
||||
Feeling like helping out? Want to find an awesome server? Some awesome plugins?
|
||||
|
||||
If you'd like to help out, the best thing you can do is to fork this repository, add changes, and request a pull back in. Try to make your changes on the latest code possible so that merging doesn't take ages, but other than that we accept any improvements or changes.
|
||||
* [Website & Forums](http://tshock.co/xf/)
|
||||
* [Wiki](https://tshock.atlassian.net/wiki/display/TSHOCKPLUGINS/Home)
|
||||
* [IRC: #tshock @ irc.rizon.net](http://tshock.co/xf/index.php?ezirc/)
|
||||
|
||||
----
|
||||
## Download
|
||||
|
||||
### Teamspeak
|
||||
|
||||
We communicate on the ShankShock Temspeak server whilst programming.
|
||||
|
||||
__IP__: ts3.shankshock.com
|
||||
|
||||
__Port__: 9987
|
||||
|
||||
### IRC
|
||||
|
||||
We love IRC (although a little less than Teamspeak). If you need support, or just want to hang around, feel free to join.
|
||||
|
||||
__IP__: irc.shankshock.com
|
||||
|
||||
__Channel__: #terraria-dev or #terraria
|
||||
|
||||
----
|
||||
|
||||
### Pull Request Dev Guidelines
|
||||
|
||||
These guidelines are for contributors. If you do not follow these guidelines your commits will be reverted.
|
||||
|
||||
Required:
|
||||
- Follow the code style. We generally use microsofts except for m_ infront of private variables.
|
||||
- Do not push unfinished features to the master branch, instead create a remote branch and push to that.
|
||||
- Do not push untested code to the master branch, instead push to the test branch.
|
||||
- Document all compatibility issues in the COMPATIBILITY file. (IE file formats changing)
|
||||
- DO NOT MASS COMMIT. Commit changes as you go (without pushing). That way when you push we don't get a thousand changes with a 1-3 line commit message.
|
||||
|
||||
Optional:
|
||||
- Build Version Increment (http://autobuildversion.codeplex.com/).
|
||||
|
||||
----
|
||||
|
||||
### Dev Team Guidelines
|
||||
|
||||
These guidelines are to be followed by all developers with commit level access to this repository:
|
||||
|
||||
- Do not, for any reason, submit code to the master branch before it hits the development branch first. If the development branch is far ahead, and a new bug fix is going out, branch master, then merge with master and remove your branch.
|
||||
- If you are found to do this, you will be the person merging and rebasing your code to fit general-devel.
|
||||
- Prior to posting any version on the website, you must tick the version in AssemblyInfo.cs. This is the versioning formula:
|
||||
- Major.Minor.Revision.BuildDate (tick Revision if you're fixing prior to an actual planned release)
|
||||
- Do not release any development builds on the forums without consulting another developer first.
|
||||
- __Document code prior to marking it done in JIRA__
|
||||
- Move any un-tested code to the "Needs Validation" section on JIRA prior to marking it as done.
|
||||
- Do not push changes to any branch without a proper issue being assigned in JIRA. If a feature isn't planned for this release, __it shouldn't be in the repo about to be released__.
|
||||
- Submit all pull requests to the general-devel branch prior to the master branch, or you will be ignored.
|
||||
* [Github Releases](https://github.com/TShock/TShock/releases)
|
||||
* [Download Archive](https://github.com/TShock/TShock/downloads)
|
||||
* [Latest Version (4.0.5)](https://s3.amazonaws.com/tshock/TShock+4.0.5.zip)
|
||||
|
|
|
|||
26
TShock.sln
26
TShock.sln
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 11
|
||||
# Visual Studio 2010
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{755F5B05-0924-47E9-9563-26EB20FE3F67}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
Local.testsettings = Local.testsettings
|
||||
|
|
@ -9,8 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockAPI", "TShockAPI\TShockAPI.csproj", "{49606449-072B-4CF5-8088-AA49DA586694}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockDBEditor", "DBEditor\TShockDBEditor.csproj", "{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{F3742F51-D7BF-4754-A68A-CD944D2A21FF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TShockRestTestPlugin", "TShockRestTestPlugin\TShockRestTestPlugin.csproj", "{F2FEDAFB-58DE-4611-9168-A86112C346C7}"
|
||||
|
|
@ -38,16 +36,12 @@ Global
|
|||
{49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{49606449-072B-4CF5-8088-AA49DA586694}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{49606449-072B-4CF5-8088-AA49DA586694}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Debug|x86.Build.0 = Debug|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Release|x86.ActiveCfg = Release|x86
|
||||
{F1AE395C-6B4D-40E0-8BF8-0D8A126488D3}.Release|x86.Build.0 = Release|x86
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
|
|
@ -58,12 +52,6 @@ Global
|
|||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{F2FEDAFB-58DE-4611-9168-A86112C346C7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{F3742F51-D7BF-4754-A68A-CD944D2A21FF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
|
@ -60,22 +61,22 @@ namespace TShockAPI
|
|||
if (worldpath != null && !Directory.Exists(worldpath))
|
||||
Directory.CreateDirectory(worldpath);
|
||||
|
||||
TShock.Utils.Broadcast("Server map saving, potential lag spike");
|
||||
TShock.Utils.Broadcast("Server map saving, potential lag spike.");
|
||||
Console.WriteLine("Backing up world...");
|
||||
|
||||
SaveManager.Instance.SaveWorld();
|
||||
Console.WriteLine("World backed up");
|
||||
Console.WriteLine("World backed up.");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Log.Info(string.Format("World backed up ({0})", Main.worldPathName));
|
||||
Log.Info(string.Format("World backed up ({0}).", Main.worldPathName));
|
||||
|
||||
Main.worldPathName = worldname;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine("Backup failed");
|
||||
Console.WriteLine("Backup failed!");
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
Log.Error("Backup failed");
|
||||
Log.Error("Backup failed!");
|
||||
Log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,33 +15,36 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using Rests;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public class ConfigFile
|
||||
{
|
||||
[Description(
|
||||
"The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))"
|
||||
"The equation for calculating invasion size is 100 + (multiplier * (number of active players with greater than 200 health))."
|
||||
)] public int InvasionMultiplier = 1;
|
||||
|
||||
[Description("The default maximum mobs that will spawn per wave. Higher means more mobs in that wave.")] public int
|
||||
DefaultMaximumSpawns = 5;
|
||||
|
||||
[Description("The delay between waves. Shorter values lead to less mobs.")] public int DefaultSpawnRate = 600;
|
||||
[Description("The delay between waves. Lower values lead to more mobs.")] public int DefaultSpawnRate = 600;
|
||||
[Description("The port the server runs on.")] public int ServerPort = 7777;
|
||||
[Description("Enable or disable the whitelist based on IP addresses in whitelist.txt")] public bool EnableWhitelist;
|
||||
|
||||
[Description(
|
||||
"Enable the ability for invaison size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn que for the map."
|
||||
"Enable the ability for invasion size to never decrease. Make sure to run /invade, and note that this adds 2 million+ goblins to the spawn queue for the map."
|
||||
)] public bool InfiniteInvasion;
|
||||
|
||||
[Description("Set the server pvp mode. Vaild types are, \"normal\", \"always\", \"disabled\"")] public string PvPMode
|
||||
[Description("Set the server pvp mode. Valid types are, \"normal\", \"always\", and \"disabled.\"")] public string PvPMode
|
||||
= "normal";
|
||||
|
||||
[Description("Prevents tiles from being placed within SpawnProtectionRadius of the default spawn.")] public bool
|
||||
|
|
@ -73,48 +76,48 @@ namespace TShockAPI
|
|||
|
||||
[Description("Hardcore players ONLY. This means softcore players cannot join.")] public bool HardcoreOnly;
|
||||
[Description("Mediumcore players ONLY. This means softcore players cannot join.")] public bool MediumcoreOnly;
|
||||
[Description("Kicks a Hardcore player on death.")] public bool KickOnMediumcoreDeath;
|
||||
[Description("Bans a Hardcore player on death.")] public bool BanOnMediumcoreDeath;
|
||||
[Description("Kicks a hardcore player on death.")] public bool KickOnMediumcoreDeath;
|
||||
[Description("Bans a hardcore player on death.")] public bool BanOnMediumcoreDeath;
|
||||
|
||||
[Description("Enable/Disable Terrarias built in auto save")] public bool AutoSave = true;
|
||||
[Description("Enable/disable Terraria's built in auto save.")] public bool AutoSave = true;
|
||||
|
||||
[Description("Number of failed login attempts before kicking the player.")] public int MaximumLoginAttempts = 3;
|
||||
|
||||
[Description("Not implemented")] public string RconPassword = "";
|
||||
[Description("Not implemented")] public int RconPort = 7777;
|
||||
[Description("Not implemented.")] public string RconPassword = "";
|
||||
[Description("Not implemented.")] public int RconPort = 7777;
|
||||
|
||||
[Description("Used when replying to a rest /status request or sent to the client when UseServerName is true.")] public string ServerName = "";
|
||||
[Description("Sends ServerName in place of the world name to clients.")] public bool UseServerName = false;
|
||||
[Description("Not implemented")] public string MasterServer = "127.0.0.1";
|
||||
[Description("Not implemented.")] public string MasterServer = "127.0.0.1";
|
||||
|
||||
[Description("Valid types are \"sqlite\" and \"mysql\"")] public string StorageType = "sqlite";
|
||||
|
||||
[Description("The MySQL Hostname and port to direct connections to")] public string MySqlHost = "localhost:3306";
|
||||
[Description("The MySQL hostname and port to direct connections to")] public string MySqlHost = "localhost:3306";
|
||||
[Description("Database name to connect to")] public string MySqlDbName = "";
|
||||
[Description("Database username to connect with")] public string MySqlUsername = "";
|
||||
[Description("Database password to connect with")] public string MySqlPassword = "";
|
||||
|
||||
[Description("Bans a Mediumcore player on death.")] public string MediumcoreBanReason = "Death results in a ban";
|
||||
[Description("Kicks a Mediumcore player on death.")] public string MediumcoreKickReason = "Death results in a kick";
|
||||
[Description("Bans a mediumcore player on death.")] public string MediumcoreBanReason = "Death results in a ban";
|
||||
[Description("Kicks a mediumcore player on death.")] public string MediumcoreKickReason = "Death results in a kick";
|
||||
|
||||
[Description("Enables DNS resolution of incoming connections with GetGroupForIPExpensive.")] public bool
|
||||
EnableDNSHostResolution;
|
||||
|
||||
[Description("Enables kicking of banned users by matching their IP Address")] public bool EnableIPBans = true;
|
||||
[Description("Enables kicking of banned users by matching their IP Address.")] public bool EnableIPBans = true;
|
||||
|
||||
[Description("Enables kicking of banned users by matching their Character Name")] public bool EnableBanOnUsernames;
|
||||
[Description("Enables kicking of banned users by matching their Character Name.")] public bool EnableBanOnUsernames;
|
||||
|
||||
[Description("Selects the default group name to place new registrants under")] public string
|
||||
[Description("Selects the default group name to place new registrants under.")] public string
|
||||
DefaultRegistrationGroupName = "default";
|
||||
|
||||
[Description("Selects the default group name to place non registered users under")] public string
|
||||
DefaultGuestGroupName = "guest";
|
||||
|
||||
[Description("Force-Disable printing logs to players with the log permission")] public bool DisableSpewLogs = true;
|
||||
[Description("Force-disable printing logs to players with the log permission.")] public bool DisableSpewLogs = true;
|
||||
|
||||
[Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms")] public string HashAlgorithm = "sha512";
|
||||
[Description("Valid types are \"sha512\", \"sha256\", \"md5\", append with \"-xp\" for the xp supported algorithms.")] public string HashAlgorithm = "sha512";
|
||||
|
||||
[Description("Buffers up the packets and sends them out at the end of each frame")] public bool BufferPackets = true;
|
||||
[Description("Buffers up the packets and sends them out at the end of each frame.")] public bool BufferPackets = true;
|
||||
|
||||
[Description("String that is used when kicking people when the server is full.")] public string ServerFullReason =
|
||||
"Server is full";
|
||||
|
|
@ -129,95 +132,95 @@ namespace TShockAPI
|
|||
|
||||
[Description("This will announce a player's location on join")] public bool EnableGeoIP;
|
||||
|
||||
[Description("This will turn on a token requirement for the /status API endpoint.")] public bool
|
||||
[Description("This will turn on token requirement for the public REST API endpoints.")] public bool
|
||||
EnableTokenEndpointAuthentication;
|
||||
|
||||
[Description("Deprecated. Use ServerName instead.")] public string ServerNickname = "TShock Server";
|
||||
|
||||
[Description("Enable/Disable the rest api.")] public bool RestApiEnabled;
|
||||
[Description("Enable/disable the rest api.")] public bool RestApiEnabled;
|
||||
|
||||
[Description("This is the port which the rest api will listen on.")] public int RestApiPort = 7878;
|
||||
|
||||
[Description("Disable tombstones for all players.")] public bool DisableTombstones = true;
|
||||
|
||||
[Description("Displays a player's IP on join to everyone who has the log permission")] public bool DisplayIPToAdmins;
|
||||
[Description("Displays a player's IP on join to everyone who has the log permission.")] public bool DisplayIPToAdmins;
|
||||
|
||||
[Description(
|
||||
"Some tiles are 'fixed' by not letting TShock handle them. Disabling this may break certain asthetic tiles.")] public
|
||||
"Some tiles are 'fixed' by not letting TShock handle them. Disabling this may break certain aesthetic tiles.")] public
|
||||
bool EnableInsecureTileFixes = true;
|
||||
|
||||
[Description("Kicks users using a proxy as identified with the GeoIP database")] public bool KickProxyUsers = true;
|
||||
[Description("Kicks users using a proxy as identified with the GeoIP database.")] public bool KickProxyUsers = true;
|
||||
|
||||
[Description("Disables hardmode, can't never be activated. Overrides /starthardmode")] public bool DisableHardmode;
|
||||
[Description("Disables hardmode, can't never be activated. Overrides /starthardmode.")] public bool DisableHardmode;
|
||||
|
||||
[Description("Disables Dungeon Guardian from being spawned by player packets, this will instead force a respawn")] public bool DisableDungeonGuardian;
|
||||
[Description("Disables the dungeon guardian from being spawned by player packets, this will instead force a respawn.")] public bool DisableDungeonGuardian;
|
||||
|
||||
[Description("Enable Server Side Inventory checks, EXPERIMENTAL")] public bool ServerSideInventory;
|
||||
[Description("Enable server side inventory checks, EXPERIMENTAL")] public bool ServerSideInventory;
|
||||
|
||||
[Description("How often SSI should save, in minutes")] public int ServerSideInventorySave = 15;
|
||||
[Description("How often SSI should save, in minutes.")] public int ServerSideInventorySave = 15;
|
||||
|
||||
[Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON")] public int LogonDiscardThreshold=250;
|
||||
[Description("Time, in milliseconds, to disallow discarding items after logging in when ServerSideInventory is ON.")] public int LogonDiscardThreshold=250;
|
||||
|
||||
[Description("Disables reporting of playercount to the stat system.")] public bool DisablePlayerCountReporting;
|
||||
[Description("Disables clown bomb projectiles from spawning.")] public bool DisableClownBombs;
|
||||
|
||||
[Description("Disables clown bomb projectiles from spawning")] public bool DisableClownBombs;
|
||||
|
||||
[Description("Disables snow ball projectiles from spawning")] public bool DisableSnowBalls;
|
||||
[Description("Disables snow ball projectiles from spawning.")] public bool DisableSnowBalls;
|
||||
|
||||
[Description(
|
||||
"Change ingame chat format, {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message"
|
||||
"Changes ingame chat format: {0} = Group Name, {1} = Group Prefix, {2} = Player Name, {3} = Group Suffix, {4} = Chat Message"
|
||||
)] public string ChatFormat = "{1}{2}{3}: {4}";
|
||||
|
||||
[Description("Change the chat format when using chat above heads. This begins with a player name wrapped in brackets, as per Terraria's formatting. Same formatting as ChatFormat.")] public string ChatAboveHeadsFormat = "{4}";
|
||||
|
||||
[Description("Force the world time to be normal, day, or night")] public string ForceTime = "normal";
|
||||
[Description("Force the world time to be normal, day, or night.")] public string ForceTime = "normal";
|
||||
|
||||
[Description("Disable/Revert a player if they exceed this number of tile kills within 1 second.")] public int
|
||||
[Description("Disables/reverts a player if this number of tile kills is exceeded within 1 second.")] public int
|
||||
TileKillThreshold = 60;
|
||||
|
||||
[Description("Disable/Revert a player if they exceed this number of tile places within 1 second.")] public int
|
||||
[Description("Disables/reverts a player if this number of tile places is exceeded within 1 second.")]
|
||||
public int
|
||||
TilePlaceThreshold = 20;
|
||||
|
||||
[Description("Disable a player if they exceed this number of liquid sets within 1 second.")] public int
|
||||
[Description("Disables a player if this number of liquid sets is exceeded within 1 second.")] public int
|
||||
TileLiquidThreshold = 15;
|
||||
|
||||
[Description("Disable a player if they exceed this number of projectile new within 1 second.")] public int
|
||||
[Description("Disable a player if this number of projectiles is created within 1 second.")]
|
||||
public int
|
||||
ProjectileThreshold = 50;
|
||||
|
||||
[Description("Ignore shrapnel from crystal bullets for Projectile Threshold.")] public bool
|
||||
[Description("Ignore shrapnel from crystal bullets for projectile threshold.")] public bool
|
||||
ProjIgnoreShrapnel = true;
|
||||
|
||||
[Description("Require all players to register or login before being allowed to play.")] public bool RequireLogin;
|
||||
[Description("Requires all players to register or login before being allowed to play.")] public bool RequireLogin;
|
||||
|
||||
[Description(
|
||||
"Disables Invisibility potions from being used in PvP (Note, they can use them on the client, but the effect isn't sent to the rest of the server)"
|
||||
"Disables invisibility potions from being used in PvP (Note, can be used in the client, but the effect isn't sent to the rest of the server)."
|
||||
)] public bool DisableInvisPvP;
|
||||
|
||||
[Description("The maximum distance players disabled for various reasons can move from")] public int
|
||||
[Description("The maximum distance players disabled for various reasons can move from.")] public int
|
||||
MaxRangeForDisabled = 10;
|
||||
|
||||
[Description("Server password required to join server")] public string ServerPassword = "";
|
||||
[Description("Server password required to join the server.")] public string ServerPassword = "";
|
||||
|
||||
[Description("Protect chests with region and build permissions")] public bool RegionProtectChests;
|
||||
[Description("Protect chests with region and build permissions.")] public bool RegionProtectChests;
|
||||
|
||||
[Description("Disable users from being able to login with account password when joining")] public bool
|
||||
[Description("Disable users from being able to login with account password when joining.")] public bool
|
||||
DisableLoginBeforeJoin;
|
||||
|
||||
[Description("Allows users to register any username with /register")] public bool AllowRegisterAnyUsername;
|
||||
[Description("Allows users to register any username with /register.")] public bool AllowRegisterAnyUsername;
|
||||
|
||||
[Description("Allows users to login with any username with /login")] public bool AllowLoginAnyUsername = true;
|
||||
[Description("Allows users to login with any username with /login.")] public bool AllowLoginAnyUsername = true;
|
||||
|
||||
[Description("The maximum damage a player/npc can inflict")] public int MaxDamage = 175;
|
||||
[Description("The maximum damage a player/npc can inflict.")] public int MaxDamage = 175;
|
||||
|
||||
[Description("The maximum damage a projectile can inflict")] public int MaxProjDamage = 175;
|
||||
[Description("The maximum damage a projectile can inflict.")] public int MaxProjDamage = 175;
|
||||
|
||||
[Description("Ignores checking to see if player 'can' update a projectile")] public bool IgnoreProjUpdate = false;
|
||||
[Description("Ignores checking to see if player 'can' update a projectile.")] public bool IgnoreProjUpdate = false;
|
||||
|
||||
[Description("Ignores checking to see if player 'can' kill a projectile")] public bool IgnoreProjKill = false;
|
||||
[Description("Ignores checking to see if player 'can' kill a projectile.")] public bool IgnoreProjKill = false;
|
||||
|
||||
[Description("Ignores all no clip checks for players")] public bool IgnoreNoClip = false;
|
||||
[Description("Ignores all no clip checks for players.")] public bool IgnoreNoClip = false;
|
||||
|
||||
[Description("Allow Ice placement even when user does not have canbuild")] public bool AllowIce = false;
|
||||
[Description("Allow ice placement even when user does not have canbuild.")] public bool AllowIce = false;
|
||||
|
||||
[Description("Allows corrutption to spread when a world is hardmode.")] public bool AllowCorruptionCreep = true;
|
||||
|
||||
|
|
@ -229,17 +232,40 @@ namespace TShockAPI
|
|||
|
||||
[Description("How many things a statue spawns can exist in the world before it stops spawning. Default = 10")] public int StatueSpawnWorld = 10;
|
||||
|
||||
[Description("Prevent banned items from being /i or /give")] public bool PreventBannedItemSpawn = false;
|
||||
[Description("Prevent banned items from being /i or /give.")] public bool PreventBannedItemSpawn = false;
|
||||
|
||||
[Description("Prevent banks on SSI")] public bool DisablePiggybanksOnSSI = false;
|
||||
[Description("Prevent banks on SSI.")] public bool DisablePiggybanksOnSSI = false;
|
||||
|
||||
[Description("Prevent players from interacting with the world if dead")] public bool PreventDeadModification =
|
||||
false;
|
||||
[Description("Prevent players from interacting with the world if dead.")] public bool PreventDeadModification =
|
||||
true;
|
||||
|
||||
[Description("Displays chat messages above players' heads, but will disable chat prefixes to compensate.")] public
|
||||
bool EnableChatAboveHeads = false;
|
||||
|
||||
[Description("Hide stat tracker console messages.")] public bool HideStatTrackerDebugMessages = true;
|
||||
[Description("Force Christmas only events to occur all year.")] public bool ForceXmas = false;
|
||||
|
||||
[Description("Allows groups on the banned item allowed list to spawn banned items.")] public bool AllowAllowedGroupsToSpawnBannedItems = false;
|
||||
|
||||
[Description("Allows stacks in chests to be beyond the stack limit")] public bool IgnoreChestStacksOnLoad = false;
|
||||
|
||||
[Description("The path of the directory where logs should be written into.")] public string LogPath = "tshock";
|
||||
|
||||
[Description("Prevents players from placing tiles with an invalid style.")] public bool PreventInvalidPlaceStyle = true;
|
||||
|
||||
[Description("#.#.#. = Red/Blue/Green - RGB Colors for broadcasts. Max value: 255.")] public float[] BroadcastRGB =
|
||||
{127,255,212};
|
||||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
[Description(
|
||||
"Whether the REST API should use the new permission model. Note: The old permission model will become depracted in the future."
|
||||
)] public bool RestUseNewPermissionModel = true;
|
||||
|
||||
[Description("A dictionary of REST tokens that external applications may use to make queries to your server.")]
|
||||
public Dictionary<string, SecureRest.TokenData> ApplicationRestTokens = new Dictionary<string, SecureRest.TokenData>();
|
||||
|
||||
[Description("The maximum value that a character may have for health.")] public int MaxHealth = 400;
|
||||
|
||||
[Description("The maximum value that a character may have for health.")] public int MaxMana = 400;
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuration file from a given path
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,10 +15,10 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,11 +15,12 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
|
|
@ -106,7 +107,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
if (exceptions)
|
||||
throw new GroupExistsException(name);
|
||||
return "Error: Group already exists. Use /modGroup to change permissions.";
|
||||
return "Error: Group already exists. Use /modgroup to change permissions.";
|
||||
}
|
||||
|
||||
var group = new Group(name, null, chatcolor);
|
||||
|
|
@ -114,7 +115,7 @@ namespace TShockAPI.DB
|
|||
if (!string.IsNullOrWhiteSpace(parentname))
|
||||
{
|
||||
var parent = groups.FirstOrDefault(gp => gp.Name == parentname);
|
||||
if (parent == null)
|
||||
if (parent == null || name == parentname)
|
||||
{
|
||||
var error = "Invalid parent {0} for group {1}".SFormat(parentname, group.Name);
|
||||
if (exceptions)
|
||||
|
|
@ -126,15 +127,15 @@ namespace TShockAPI.DB
|
|||
}
|
||||
|
||||
string query = (TShock.Config.StorageType.ToLower() == "sqlite")
|
||||
? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);"
|
||||
: "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3";
|
||||
? "INSERT OR IGNORE INTO GroupList (GroupName, Parent, Commands, ChatColor) VALUES (@0, @1, @2, @3);"
|
||||
: "INSERT IGNORE INTO GroupList SET GroupName=@0, Parent=@1, Commands=@2, ChatColor=@3";
|
||||
if (database.Query(query, name, parentname, permissions, chatcolor) == 1)
|
||||
{
|
||||
groups.Add(group);
|
||||
return "Group " + name + " has been created successfully.";
|
||||
}
|
||||
else if (exceptions)
|
||||
throw new GroupManagerException("Failed to add group '" + name + "'");
|
||||
throw new GroupManagerException("Failed to add group '" + name + ".'");
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
@ -166,25 +167,40 @@ namespace TShockAPI.DB
|
|||
/// <param name="chatcolor">chatcolor</param>
|
||||
public void UpdateGroup(string name, string parentname, string permissions, string chatcolor)
|
||||
{
|
||||
if (!GroupExists(name))
|
||||
Group group = GetGroupByName(name);
|
||||
if (group == null)
|
||||
throw new GroupNotExistException(name);
|
||||
|
||||
Group parent = null;
|
||||
if (!string.IsNullOrWhiteSpace(parentname))
|
||||
{
|
||||
parent = groups.FirstOrDefault(gp => gp.Name == parentname);
|
||||
if (null == parent)
|
||||
throw new GroupManagerException("Invalid parent {0} for group {1}".SFormat(parentname, name));
|
||||
parent = GetGroupByName(parentname);
|
||||
if (parent == null || parent == group)
|
||||
throw new GroupManagerException("Invalid parent \"{0}\" for group \"{1}\".".SFormat(parentname, name));
|
||||
|
||||
// Check if the new parent would cause loops.
|
||||
List<Group> groupChain = new List<Group> { group, parent };
|
||||
Group checkingGroup = parent.Parent;
|
||||
while (checkingGroup != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup))
|
||||
throw new GroupManagerException(
|
||||
string.Format("Invalid parent \"{0}\" for group \"{1}\" would cause loops in the parent chain.", parentname, name));
|
||||
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: we use newgroup.XYZ to ensure any validation is also persisted to the DB
|
||||
var newgroup = new Group(name, parent, chatcolor, permissions);
|
||||
// Ensure any group validation is also persisted to the DB.
|
||||
var newGroup = new Group(name, parent, chatcolor, permissions);
|
||||
string query = "UPDATE GroupList SET Parent=@0, Commands=@1, ChatColor=@2 WHERE GroupName=@3";
|
||||
if (database.Query(query, parentname, newgroup.Permissions, newgroup.ChatColor, name) != 1)
|
||||
throw new GroupManagerException("Failed to update group '" + name + "'");
|
||||
if (database.Query(query, parentname, newGroup.Permissions, string.Format("{0},{1},{2}", newGroup.R, newGroup.G, newGroup.B), name) != 1)
|
||||
throw new GroupManagerException(string.Format("Failed to update group \"{0}\".", name));
|
||||
|
||||
groups.Remove(TShock.Utils.GetGroup(name));
|
||||
groups.Add(newgroup);
|
||||
group.ChatColor = chatcolor;
|
||||
group.Permissions = permissions;
|
||||
group.Parent = parent;
|
||||
}
|
||||
|
||||
#if COMPAT_SIGS
|
||||
|
|
@ -200,7 +216,7 @@ namespace TShockAPI.DB
|
|||
{
|
||||
if (exceptions)
|
||||
throw new GroupNotExistException(name);
|
||||
return "Error: Group doesn't exists.";
|
||||
return "Error: Group doesn't exist.";
|
||||
}
|
||||
|
||||
if (database.Query("DELETE FROM GroupList WHERE GroupName=@0", name) == 1)
|
||||
|
|
@ -209,7 +225,7 @@ namespace TShockAPI.DB
|
|||
return "Group " + name + " has been deleted successfully.";
|
||||
}
|
||||
else if (exceptions)
|
||||
throw new GroupManagerException("Failed to delete group '" + name + "'");
|
||||
throw new GroupManagerException("Failed to delete group '" + name + ".'");
|
||||
|
||||
return "";
|
||||
}
|
||||
|
|
@ -217,7 +233,7 @@ namespace TShockAPI.DB
|
|||
public String AddPermissions(String name, List<String> permissions)
|
||||
{
|
||||
if (!GroupExists(name))
|
||||
return "Error: Group doesn't exists.";
|
||||
return "Error: Group doesn't exist.";
|
||||
|
||||
var group = TShock.Utils.GetGroup(name);
|
||||
var oldperms = group.Permissions; // Store old permissions in case of error
|
||||
|
|
@ -234,7 +250,7 @@ namespace TShockAPI.DB
|
|||
public String DeletePermissions(String name, List<String> permissions)
|
||||
{
|
||||
if (!GroupExists(name))
|
||||
return "Error: Group doesn't exists.";
|
||||
return "Error: Group doesn't exist.";
|
||||
|
||||
var group = TShock.Utils.GetGroup(name);
|
||||
var oldperms = group.Permissions; // Store old permissions in case of error
|
||||
|
|
@ -250,53 +266,106 @@ namespace TShockAPI.DB
|
|||
|
||||
public void LoadPermisions()
|
||||
{
|
||||
// Create a temporary list so if there is an error it doesn't override the currently loaded groups with broken groups.
|
||||
var tempgroups = new List<Group>();
|
||||
tempgroups.Add(new SuperAdminGroup());
|
||||
|
||||
if (groups == null || groups.Count < 2)
|
||||
{
|
||||
groups.Clear();
|
||||
groups.AddRange(tempgroups);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var groupsparents = new List<Tuple<Group, string>>();
|
||||
List<Group> newGroups = new List<Group>(groups.Count);
|
||||
Dictionary<string,string> newGroupParents = new Dictionary<string, string>(groups.Count);
|
||||
using (var reader = database.QueryReader("SELECT * FROM GroupList"))
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var group = new Group(reader.Get<String>("GroupName"), null, reader.Get<String>("ChatColor"), reader.Get<String>("Commands"));
|
||||
group.Prefix = reader.Get<String>("Prefix");
|
||||
group.Suffix = reader.Get<String>("Suffix");
|
||||
groupsparents.Add(Tuple.Create(group, reader.Get<string>("Parent")));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var t in groupsparents)
|
||||
{
|
||||
var group = t.Item1;
|
||||
var parentname = t.Item2;
|
||||
if (!string.IsNullOrWhiteSpace(parentname))
|
||||
{
|
||||
var parent = groupsparents.FirstOrDefault(gp => gp.Item1.Name == parentname);
|
||||
if (parent == null)
|
||||
string groupName = reader.Get<string>("GroupName");
|
||||
if (groupName == "superadmin")
|
||||
{
|
||||
Log.ConsoleError("Invalid parent {0} for group {1}".SFormat(parentname, group.Name));
|
||||
Log.ConsoleInfo("WARNING: Group \"superadmin\" is defined in the database even though it's a reserved group name.");
|
||||
continue;
|
||||
}
|
||||
|
||||
newGroups.Add(new Group(groupName, null, reader.Get<string>("ChatColor"), reader.Get<string>("Commands")) {
|
||||
Prefix = reader.Get<string>("Prefix"),
|
||||
Suffix = reader.Get<string>("Suffix"),
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
newGroupParents.Add(groupName, reader.Get<string>("Parent"));
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
// Just in case somebody messed with the unique primary key.
|
||||
Log.ConsoleError("ERROR: Group name \"{0}\" occurs more than once. Keeping current group settings.");
|
||||
return;
|
||||
}
|
||||
group.Parent = parent.Item1;
|
||||
}
|
||||
tempgroups.Add(group);
|
||||
}
|
||||
|
||||
groups.Clear();
|
||||
groups.AddRange(tempgroups);
|
||||
try
|
||||
{
|
||||
// Get rid of deleted groups.
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
if (newGroups.All(g => g.Name != groups[i].Name))
|
||||
groups.RemoveAt(i--);
|
||||
|
||||
// Apply changed group settings while keeping the current instances and add new groups.
|
||||
foreach (Group newGroup in newGroups)
|
||||
{
|
||||
Group currentGroup = groups.FirstOrDefault(g => g.Name == newGroup.Name);
|
||||
if (currentGroup != null)
|
||||
newGroup.AssignTo(currentGroup);
|
||||
else
|
||||
groups.Add(newGroup);
|
||||
}
|
||||
|
||||
// Resolve parent groups.
|
||||
Debug.Assert(newGroups.Count == newGroupParents.Count);
|
||||
for (int i = 0; i < groups.Count; i++)
|
||||
{
|
||||
Group group = groups[i];
|
||||
string parentGroupName;
|
||||
if (!newGroupParents.TryGetValue(group.Name, out parentGroupName) || string.IsNullOrEmpty(parentGroupName))
|
||||
continue;
|
||||
|
||||
group.Parent = groups.FirstOrDefault(g => g.Name == parentGroupName);
|
||||
if (group.Parent == null)
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing non existent parent group \"{1}\", parent reference was removed.",
|
||||
group.Name, parentGroupName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group.Parent == group)
|
||||
Log.ConsoleInfo(
|
||||
"WARNING: Group \"{0}\" is referencing itself as parent group, parent reference was removed.", group.Name);
|
||||
|
||||
List<Group> groupChain = new List<Group> { group };
|
||||
Group checkingGroup = group;
|
||||
while (checkingGroup.Parent != null)
|
||||
{
|
||||
if (groupChain.Contains(checkingGroup.Parent))
|
||||
{
|
||||
Log.ConsoleError(
|
||||
"ERROR: Group \"{0}\" is referencing parent group \"{1}\" which is already part of the parent chain. Parent reference removed.",
|
||||
checkingGroup.Name, checkingGroup.Parent.Name);
|
||||
|
||||
checkingGroup.Parent = null;
|
||||
break;
|
||||
}
|
||||
groupChain.Add(checkingGroup);
|
||||
checkingGroup = checkingGroup.Parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!groups.Any(g => g is SuperAdminGroup))
|
||||
groups.Add(new SuperAdminGroup());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.ToString());
|
||||
Log.ConsoleError("Error on reloading groups: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,10 +15,10 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,13 +15,11 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using MySql.Data.MySqlClient;
|
||||
using Terraria;
|
||||
|
||||
|
|
@ -238,25 +236,21 @@ namespace TShockAPI.DB
|
|||
return false;
|
||||
}
|
||||
Region top = null;
|
||||
for (int i = 0; i < Regions.Count; i++)
|
||||
{
|
||||
if (Regions[i].InArea(x,y) )
|
||||
{
|
||||
if (top == null)
|
||||
top = Regions[i];
|
||||
else
|
||||
{
|
||||
if (Regions[i].Z > top.Z)
|
||||
top = Regions[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Region region in Regions.ToList())
|
||||
{
|
||||
if (region.InArea(x, y))
|
||||
{
|
||||
if (top == null || region.Z > top.Z)
|
||||
top = region;
|
||||
}
|
||||
}
|
||||
return top == null || top.HasPermissionToBuildInRegion(ply);
|
||||
}
|
||||
|
||||
public bool InArea(int x, int y)
|
||||
{
|
||||
foreach (Region region in Regions)
|
||||
foreach (Region region in Regions.ToList())
|
||||
{
|
||||
if (x >= region.Area.Left && x <= region.Area.Right &&
|
||||
y >= region.Area.Top && y <= region.Area.Bottom &&
|
||||
|
|
@ -271,7 +265,7 @@ namespace TShockAPI.DB
|
|||
public List<string> InAreaRegionName(int x, int y)
|
||||
{
|
||||
List<string> regions = new List<string>() { };
|
||||
foreach (Region region in Regions)
|
||||
foreach (Region region in Regions.ToList())
|
||||
{
|
||||
if (x >= region.Area.Left && x <= region.Area.Right &&
|
||||
y >= region.Area.Top && y <= region.Area.Bottom &&
|
||||
|
|
@ -283,6 +277,21 @@ namespace TShockAPI.DB
|
|||
return regions;
|
||||
}
|
||||
|
||||
public List<Region> InAreaRegion(int x, int y)
|
||||
{
|
||||
List<Region> regions = new List<Region>() { };
|
||||
foreach (Region region in Regions.ToList())
|
||||
{
|
||||
if (x >= region.Area.Left && x <= region.Area.Right &&
|
||||
y >= region.Area.Top && y <= region.Area.Bottom &&
|
||||
region.DisableBuild)
|
||||
{
|
||||
regions.Add(region);
|
||||
}
|
||||
}
|
||||
return regions;
|
||||
}
|
||||
|
||||
public static List<string> ListIDs(string MergedIDs)
|
||||
{
|
||||
return MergedIDs.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
|
|
@ -370,30 +379,36 @@ namespace TShockAPI.DB
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool AddNewUser(string regionName, String userName)
|
||||
public bool AddNewUser(string regionName, string userName)
|
||||
{
|
||||
try
|
||||
{
|
||||
string MergedIDs = string.Empty;
|
||||
string mergedIDs = string.Empty;
|
||||
using (
|
||||
var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
|
||||
var reader = database.QueryReader("SELECT UserIds FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
|
||||
Main.worldID.ToString()))
|
||||
{
|
||||
if (reader.Read())
|
||||
MergedIDs = reader.Get<string>("UserIds");
|
||||
mergedIDs = reader.Get<string>("UserIds");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(MergedIDs))
|
||||
MergedIDs = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
else
|
||||
MergedIDs = MergedIDs + "," + Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
string userIdToAdd = Convert.ToString(TShock.Users.GetUserID(userName));
|
||||
string[] ids = mergedIDs.Split(',');
|
||||
// Is the user already allowed to the region?
|
||||
if (ids.Contains(userIdToAdd))
|
||||
return true;
|
||||
|
||||
int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", MergedIDs,
|
||||
if (string.IsNullOrEmpty(mergedIDs))
|
||||
mergedIDs = userIdToAdd;
|
||||
else
|
||||
mergedIDs = string.Concat(mergedIDs, ",", userIdToAdd);
|
||||
|
||||
int q = database.Query("UPDATE Regions SET UserIds=@0 WHERE RegionName=@1 AND WorldID=@2", mergedIDs,
|
||||
regionName, Main.worldID.ToString());
|
||||
foreach (var r in Regions)
|
||||
{
|
||||
if (r.Name == regionName && r.WorldID == Main.worldID.ToString())
|
||||
r.setAllowedIDs(MergedIDs);
|
||||
r.setAllowedIDs(mergedIDs);
|
||||
}
|
||||
return q != 0;
|
||||
}
|
||||
|
|
@ -456,27 +471,33 @@ namespace TShockAPI.DB
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool AllowGroup(string regionName, string groups)
|
||||
public bool AllowGroup(string regionName, string groupName)
|
||||
{
|
||||
string groupsNew = "";
|
||||
string mergedGroups = "";
|
||||
using (
|
||||
var reader = database.QueryReader("SELECT * FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
|
||||
var reader = database.QueryReader("SELECT Groups FROM Regions WHERE RegionName=@0 AND WorldID=@1", regionName,
|
||||
Main.worldID.ToString()))
|
||||
{
|
||||
if (reader.Read())
|
||||
groupsNew = reader.Get<string>("Groups");
|
||||
mergedGroups = reader.Get<string>("Groups");
|
||||
}
|
||||
if (groupsNew != "")
|
||||
groupsNew += ",";
|
||||
groupsNew += groups;
|
||||
|
||||
int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", groupsNew,
|
||||
string[] groups = mergedGroups.Split(',');
|
||||
// Is the group already allowed to the region?
|
||||
if (groups.Contains(groupName))
|
||||
return true;
|
||||
|
||||
if (mergedGroups != "")
|
||||
mergedGroups += ",";
|
||||
mergedGroups += groupName;
|
||||
|
||||
int q = database.Query("UPDATE Regions SET Groups=@0 WHERE RegionName=@1 AND WorldID=@2", mergedGroups,
|
||||
regionName, Main.worldID.ToString());
|
||||
|
||||
Region r = GetRegionByName(regionName);
|
||||
if (r != null)
|
||||
{
|
||||
r.SetAllowedGroups(groupsNew);
|
||||
r.SetAllowedGroups(mergedGroups);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
|
@ -22,11 +23,11 @@ using Terraria;
|
|||
|
||||
namespace TShockAPI.DB
|
||||
{
|
||||
public class RemeberedPosManager
|
||||
public class RememberedPosManager
|
||||
{
|
||||
public IDbConnection database;
|
||||
|
||||
public RemeberedPosManager(IDbConnection db)
|
||||
public RememberedPosManager(IDbConnection db)
|
||||
{
|
||||
database = db;
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using MySql.Data.MySqlClient;
|
||||
|
||||
namespace TShockAPI.DB
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,9 +15,9 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using MySql.Data.MySqlClient;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
|
|
@ -22,36 +23,52 @@ namespace TShockAPI
|
|||
{
|
||||
public class FileTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Path to the file containing the rules.
|
||||
/// </summary>
|
||||
internal static string RulesPath
|
||||
{
|
||||
get { return Path.Combine(TShock.SavePath, "rules.txt"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path to the file containing the message of the day.
|
||||
/// </summary>
|
||||
internal static string MotdPath
|
||||
{
|
||||
get { return Path.Combine(TShock.SavePath, "motd.txt"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path to the file containing the whitelist.
|
||||
/// </summary>
|
||||
internal static string WhitelistPath
|
||||
{
|
||||
get { return Path.Combine(TShock.SavePath, "whitelist.txt"); }
|
||||
}
|
||||
|
||||
internal static string RememberedPosPath
|
||||
{
|
||||
get { return Path.Combine(TShock.SavePath, "oldpos.xml"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Path to the file containing the config.
|
||||
/// </summary>
|
||||
internal static string ConfigPath
|
||||
{
|
||||
get { return Path.Combine(TShock.SavePath, "config.json"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an empty file at the given path.
|
||||
/// </summary>
|
||||
/// <param name="file">The path to the file.</param>
|
||||
public static void CreateFile(string file)
|
||||
{
|
||||
File.Create(file).Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a file if the files doesn't already exist.
|
||||
/// </summary>
|
||||
/// <param name="file">The path to the files</param>
|
||||
/// <param name="data">The data to write to the file.</param>
|
||||
public static void CreateIfNot(string file, string data = "")
|
||||
{
|
||||
if (!File.Exists(file))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,22 @@
|
|||
/* GeoIPCountry.cs
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* GeoIPCountry.cs
|
||||
*
|
||||
* Copyright (C) 2008 MaxMind, Inc. All Rights Reserved.
|
||||
*
|
||||
|
|
@ -16,24 +34,6 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,13 +15,16 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TShockAPI.DB;
|
||||
using Terraria;
|
||||
using TShockAPI.Net;
|
||||
|
||||
|
|
@ -81,13 +84,23 @@ namespace TShockAPI
|
|||
/// (KillTile = 0, PlaceTile = 1, KillWall = 2, PlaceWall = 3, KillTileNoItem = 4, PlaceWire = 5, KillWire = 6)
|
||||
/// </summary>
|
||||
public byte EditType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Did the tile get destroyed successfully.
|
||||
/// </summary>
|
||||
public bool Fail { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used when a tile is placed to denote a subtype of tile. (e.g. for tile id 21: Chest = 0, Gold Chest = 1)
|
||||
/// </summary>
|
||||
public byte Style { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TileEdit - called when a tile is placed or destroyed
|
||||
/// </summary>
|
||||
public static HandlerList<TileEditEventArgs> TileEdit;
|
||||
private static bool OnTileEdit(TSPlayer ply, int x, int y, byte type, byte editType)
|
||||
private static bool OnTileEdit(TSPlayer ply, int x, int y, byte type, byte editType, bool fail, byte style)
|
||||
{
|
||||
if (TileEdit == null)
|
||||
return false;
|
||||
|
|
@ -98,7 +111,9 @@ namespace TShockAPI
|
|||
X = x,
|
||||
Y = y,
|
||||
Type = type,
|
||||
EditType = editType
|
||||
EditType = editType,
|
||||
Fail = fail,
|
||||
Style = style
|
||||
};
|
||||
TileEdit.Invoke(null, args);
|
||||
return args.Handled;
|
||||
|
|
@ -1183,6 +1198,14 @@ namespace TShockAPI
|
|||
byte prefix = args.Data.ReadInt8();
|
||||
short type = args.Data.ReadInt16();
|
||||
|
||||
// Players send a slot update packet for each inventory slot right after they've joined.
|
||||
bool bypassTrashCanCheck = false;
|
||||
if (plr == args.Player.Index && !args.Player.HasSentInventory && slot == NetItem.maxNetInventory)
|
||||
{
|
||||
args.Player.HasSentInventory = true;
|
||||
bypassTrashCanCheck = true;
|
||||
}
|
||||
|
||||
if (OnPlayerSlot(plr, slot, stack, prefix, type))
|
||||
return true;
|
||||
|
||||
|
|
@ -1196,6 +1219,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
// Garabage? Or will it cause some internal initialization or whatever?
|
||||
var item = new Item();
|
||||
item.netDefaults(type);
|
||||
item.Prefix(prefix);
|
||||
|
|
@ -1204,6 +1228,13 @@ namespace TShockAPI
|
|||
{
|
||||
args.Player.PlayerData.StoreSlot(slot, type, prefix, stack);
|
||||
}
|
||||
else if (
|
||||
TShock.Config.ServerSideInventory && TShock.Config.DisableLoginBeforeJoin && !bypassTrashCanCheck &&
|
||||
args.Player.HasSentInventory && !args.Player.Group.HasPermission(Permissions.bypassinventorychecks)
|
||||
) {
|
||||
// The player might have moved an item to their trash can before they performed a single login attempt yet.
|
||||
args.Player.IgnoreActionsForClearingTrashCan = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1220,7 +1251,7 @@ namespace TShockAPI
|
|||
if (args.Player.FirstMaxHP == 0)
|
||||
args.Player.FirstMaxHP = max;
|
||||
|
||||
if (max > 400 && max > args.Player.FirstMaxHP)
|
||||
if (max > TShock.Config.MaxHealth && max > args.Player.FirstMaxHP)
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, "Hacked Client Detected.", true);
|
||||
return false;
|
||||
|
|
@ -1246,7 +1277,7 @@ namespace TShockAPI
|
|||
if (args.Player.FirstMaxMP == 0)
|
||||
args.Player.FirstMaxMP = max;
|
||||
|
||||
if (max > 400 && max > args.Player.FirstMaxMP)
|
||||
if (max > TShock.Config.MaxMana && max > args.Player.FirstMaxMP)
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, "Hacked Client Detected.", true);
|
||||
return false;
|
||||
|
|
@ -1330,6 +1361,10 @@ namespace TShockAPI
|
|||
return true;
|
||||
|
||||
string password = Encoding.UTF8.GetString(args.Data.ReadBytes((int) (args.Data.Length - args.Data.Position - 1)));
|
||||
|
||||
if (Hooks.PlayerHooks.OnPlayerPreLogin(args.Player, args.Player.Name, password))
|
||||
return true;
|
||||
|
||||
var user = TShock.Users.GetUserByName(args.Player.Name);
|
||||
if (user != null && !TShock.Config.DisableLoginBeforeJoin)
|
||||
{
|
||||
|
|
@ -1353,11 +1388,13 @@ namespace TShockAPI
|
|||
}
|
||||
else if (!TShock.CheckInventory(args.Player))
|
||||
{
|
||||
args.Player.LoginFailsBySsi = true;
|
||||
args.Player.SendMessage("Login Failed, Please fix the above errors then /login again.", Color.Cyan);
|
||||
args.Player.IgnoreActionsForClearingTrashCan = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
args.Player.LoginFailsBySsi = false;
|
||||
|
||||
if (group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
args.Player.IgnoreActionsForCheating = "none";
|
||||
|
|
@ -1366,6 +1403,7 @@ namespace TShockAPI
|
|||
args.Player.IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
args.Player.Group = group;
|
||||
args.Player.tempGroup = null;
|
||||
args.Player.UserAccountName = args.Player.Name;
|
||||
args.Player.UserID = TShock.Users.GetUserID(args.Player.UserAccountName);
|
||||
args.Player.IsLoggedIn = true;
|
||||
|
|
@ -1377,7 +1415,8 @@ namespace TShockAPI
|
|||
TShock.InventoryDB.InsertPlayerData(args.Player);
|
||||
}
|
||||
args.Player.SendMessage("Authenticated as " + args.Player.Name + " successfully.", Color.LimeGreen);
|
||||
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user: " + args.Player.Name);
|
||||
Log.ConsoleInfo(args.Player.Name + " authenticated successfully as user " + args.Player.Name + ".");
|
||||
Hooks.PlayerHooks.OnPlayerPostLogin(args.Player);
|
||||
return true;
|
||||
}
|
||||
TShock.Utils.ForceKick(args.Player, "Invalid user account password.", true);
|
||||
|
|
@ -1393,11 +1432,11 @@ namespace TShockAPI
|
|||
NetMessage.SendData((int) PacketTypes.WorldInfo, args.Player.Index);
|
||||
return true;
|
||||
}
|
||||
TShock.Utils.ForceKick(args.Player, "Incorrect Server Password", true);
|
||||
TShock.Utils.ForceKick(args.Player, "Incorrect server password", true);
|
||||
return true;
|
||||
}
|
||||
|
||||
TShock.Utils.ForceKick(args.Player, "Bad Password Attempt", true);
|
||||
TShock.Utils.ForceKick(args.Player, "Bad password attempt", true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1406,9 +1445,15 @@ namespace TShockAPI
|
|||
if (args.Player.RequestedSection)
|
||||
return true;
|
||||
args.Player.RequestedSection = true;
|
||||
if (TShock.HackedHealth(args.Player) && !args.Player.Group.HasPermission(Permissions.ignorestathackdetection))
|
||||
if (String.IsNullOrEmpty(args.Player.Name))
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, "You have Hacked Health/Mana, Please use a different character.", true);
|
||||
TShock.Utils.ForceKick(args.Player, "Blank name.", true);
|
||||
return true;
|
||||
}
|
||||
if (TShock.HackedStats(args.Player) && !args.Player.Group.HasPermission(Permissions.ignorestathackdetection))
|
||||
{
|
||||
TShock.Utils.ForceKick(args.Player, "You have hacked health/mana, please use a different character.", true);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorestackhackdetection))
|
||||
|
|
@ -1430,13 +1475,15 @@ namespace TShockAPI
|
|||
Log.Info(string.Format("{0} ({1}) from '{2}' group from '{3}' joined. ({4}/{5})", args.Player.Name, args.Player.IP,
|
||||
args.Player.Group.Name, args.Player.Country, TShock.Utils.ActivePlayers(),
|
||||
TShock.Config.MaxSlots));
|
||||
TShock.Utils.Broadcast(args.Player.Name + " has joined from the " + args.Player.Country, Color.Yellow);
|
||||
if (!args.Player.SilentJoinInProgress)
|
||||
TShock.Utils.Broadcast(string.Format("{0} ({1}) has joined.", args.Player.Name, args.Player.Country), Color.Yellow);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Info(string.Format("{0} ({1}) from '{2}' group joined. ({3}/{4})", args.Player.Name, args.Player.IP,
|
||||
args.Player.Group.Name, TShock.Utils.ActivePlayers(), TShock.Config.MaxSlots));
|
||||
TShock.Utils.Broadcast(args.Player.Name + " has joined", Color.Yellow);
|
||||
if (!args.Player.SilentJoinInProgress)
|
||||
TShock.Utils.Broadcast(args.Player.Name + " has joined.", Color.Yellow);
|
||||
}
|
||||
|
||||
if (TShock.Config.DisplayIPToAdmins)
|
||||
|
|
@ -1638,30 +1685,77 @@ namespace TShockAPI
|
|||
var tileX = args.Data.ReadInt32();
|
||||
var tileY = args.Data.ReadInt32();
|
||||
var tiletype = args.Data.ReadInt8();
|
||||
if (OnTileEdit(args.Player, tileX, tileY, tiletype, type))
|
||||
var fail = tiletype == 1;
|
||||
var style = args.Data.ReadInt8();
|
||||
if (OnTileEdit(args.Player, tileX, tileY, tiletype, type, fail, style))
|
||||
return true;
|
||||
if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY)
|
||||
if (!TShock.Utils.TileValid(tileX, tileY))
|
||||
return false;
|
||||
|
||||
if (args.Player.Dead && TShock.Config.PreventDeadModification)
|
||||
return true;
|
||||
|
||||
if (args.Player.AwaitingName)
|
||||
{
|
||||
var protectedregions = TShock.Regions.InAreaRegionName(tileX, tileY);
|
||||
if (protectedregions.Count == 0)
|
||||
{
|
||||
args.Player.SendMessage("Region is not protected", Color.Yellow);
|
||||
}
|
||||
else
|
||||
{
|
||||
string regionlist = string.Join(",", protectedregions.ToArray());
|
||||
args.Player.SendMessage("Region Name(s): " + regionlist, Color.Yellow);
|
||||
}
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
args.Player.AwaitingName = false;
|
||||
return true;
|
||||
}
|
||||
if (args.Player.AwaitingName)
|
||||
{
|
||||
Debug.Assert(args.Player.AwaitingNameParameters != null);
|
||||
|
||||
bool includeUnprotected = false;
|
||||
bool includeZIndexes = false;
|
||||
bool persistentMode = false;
|
||||
foreach (string parameter in args.Player.AwaitingNameParameters)
|
||||
{
|
||||
if (parameter.Equals("-u", StringComparison.InvariantCultureIgnoreCase))
|
||||
includeUnprotected = true;
|
||||
if (parameter.Equals("-z", StringComparison.InvariantCultureIgnoreCase))
|
||||
includeZIndexes = true;
|
||||
if (parameter.Equals("-p", StringComparison.InvariantCultureIgnoreCase))
|
||||
persistentMode = true;
|
||||
}
|
||||
|
||||
List<string> outputRegions = new List<string>();
|
||||
foreach (Region region in TShock.Regions.Regions.OrderBy(r => r.Z).Reverse())
|
||||
{
|
||||
if (!includeUnprotected && !region.DisableBuild)
|
||||
continue;
|
||||
if (tileX < region.Area.Left || tileX > region.Area.Right)
|
||||
continue;
|
||||
if (tileY < region.Area.Top || tileY > region.Area.Bottom)
|
||||
continue;
|
||||
|
||||
string format = "{1}";
|
||||
if (includeZIndexes)
|
||||
format = "{1} (z:{0})";
|
||||
|
||||
outputRegions.Add(string.Format(format, region.Z, region.Name));
|
||||
}
|
||||
|
||||
if (outputRegions.Count == 0)
|
||||
{
|
||||
if (includeUnprotected)
|
||||
args.Player.SendMessage("There are no regions at this point.", Color.Yellow);
|
||||
else
|
||||
args.Player.SendMessage("There are no regions at this point or they are not protected.", Color.Yellow);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (includeUnprotected)
|
||||
args.Player.SendSuccessMessage("Regions at this point:");
|
||||
else
|
||||
args.Player.SendSuccessMessage("Protected regions at this point:");
|
||||
|
||||
foreach (string line in PaginationTools.BuildLinesFromTerms(outputRegions))
|
||||
args.Player.SendMessage(line, Color.White);
|
||||
}
|
||||
|
||||
if (!persistentMode)
|
||||
{
|
||||
args.Player.AwaitingName = false;
|
||||
args.Player.AwaitingNameParameters = null;
|
||||
}
|
||||
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.Player.AwaitingTempPoint > 0)
|
||||
{
|
||||
|
|
@ -1673,35 +1767,96 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (type == 1 || type == 3)
|
||||
byte[] rightClickKill = new byte[] { 4, 13, 33, 49, 50, 128};
|
||||
Item selectedItem = args.TPlayer.inventory[args.TPlayer.selectedItem];
|
||||
if (type == 0 && Main.tile[tileX, tileY].type != 127 && !Main.tileCut[Main.tile[tileX, tileY].type] && !rightClickKill.Contains(Main.tile[tileX, tileY].type))
|
||||
{
|
||||
if (tiletype >= ((type == 1) ? Main.maxTileSets : Main.maxWallTypes))
|
||||
// If the tile is an axe tile and they aren't selecting an axe, they're hacking.
|
||||
if (Main.tileAxe[Main.tile[tileX, tileY].type] && selectedItem.axe == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if ((tiletype == 29 || tiletype == 97) && TShock.Config.ServerSideInventory && TShock.Config.DisablePiggybanksOnSSI)
|
||||
{
|
||||
args.Player.SendMessage("You cannot place this tile, server side inventory is enabled.", Color.Red);
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (tiletype == 48 && !args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Spike", args.Player))
|
||||
// If the tile is a hammer tile and they aren't selecting an hammer, they're hacking.
|
||||
else if (Main.tileHammer[Main.tile[tileX, tileY].type] && selectedItem.hammer == 0)
|
||||
{
|
||||
args.Player.Disable("Used banned spikes without permission.");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (type == 1 && tiletype == 21 && TShock.Utils.MaxChests())
|
||||
// If the tile is a pickaxe tile and they aren't selecting an pickaxe, they're hacking.
|
||||
else if ((!Main.tileAxe[Main.tile[tileX, tileY].type] && !Main.tileHammer[Main.tile[tileX, tileY].type]) && selectedItem.pick == 0)
|
||||
{
|
||||
args.Player.SendMessage("Reached the world's max chest limit, unable to place more.", Color.Red);
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (tiletype == 141 && !args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Explosives", args.Player))
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
// If they aren't selecting an hammer, they're hacking.
|
||||
if (selectedItem.hammer == 0)
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type == 1 || type == 3)
|
||||
{
|
||||
if (type == 1 && TShock.Config.PreventInvalidPlaceStyle && ((tiletype == 4 && style > 8) ||
|
||||
(tiletype == 13 && style > 4) || (tiletype == 15 && style > 1) || (tiletype == 21 && style > 6) ||
|
||||
(tiletype == 82 && style > 5) || (tiletype == 91 && style > 3) || (tiletype == 105 && style > 42) ||
|
||||
(tiletype == 135 && style > 3) || (tiletype == 139 && style > 12) || (tiletype == 144 && style > 2) ||
|
||||
(tiletype == 149 && style > 2)))
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
// If they aren't selecting the item which creates the tile or wall, they're hacking.
|
||||
if (tiletype != 127 && tiletype != (type == 1 ? selectedItem.createTile : selectedItem.createWall))
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (TShock.Itembans.ItemIsBanned(selectedItem.name, args.Player) || tiletype >= (type == 1 ? Main.maxTileSets : Main.maxWallTypes))
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (type == 1 && (tiletype == 29 || tiletype == 97) && TShock.Config.ServerSideInventory && TShock.Config.DisablePiggybanksOnSSI)
|
||||
{
|
||||
args.Player.SendMessage("You cannot place this tile because server side inventory is enabled.", Color.Red);
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (type == 1 && tiletype == 21)
|
||||
{
|
||||
if (TShock.Utils.MaxChests())
|
||||
{
|
||||
args.Player.SendMessage("The world's chest limit has been reached - unable to place more.", Color.Red);
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if ((TShock.Utils.TileValid(tileX, tileY + 1) && Main.tile[tileX, tileY + 1].type == 138) ||
|
||||
(TShock.Utils.TileValid(tileX + 1, tileY + 1) && Main.tile[tileX + 1, tileY + 1].type == 138))
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == 5)
|
||||
{
|
||||
// If they aren't selecting the wrench, they're hacking.
|
||||
if (args.TPlayer.inventory[args.TPlayer.selectedItem].type != 509)
|
||||
{
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (type == 6)
|
||||
{
|
||||
// If they aren't selecting the wire cutter, they're hacking.
|
||||
if (args.TPlayer.inventory[args.TPlayer.selectedItem].type != 510)
|
||||
{
|
||||
args.Player.Disable("Used banned explosives tile without permission.");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1750,7 +1905,7 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (type == 1 && !args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
if ( ( type == 1 || type == 3 ) && !args.Player.Group.HasPermission(Permissions.ignoreplacetiledetection))
|
||||
{
|
||||
args.Player.TilePlaceThreshold++;
|
||||
var coords = new Vector2(tileX, tileY);
|
||||
|
|
@ -1758,7 +1913,7 @@ namespace TShockAPI
|
|||
args.Player.TilesCreated.Add(coords, Main.tile[tileX, tileY].Data);
|
||||
}
|
||||
|
||||
if ((type == 0 || type == 4) && Main.tileSolid[Main.tile[tileX, tileY].type] &&
|
||||
if ((type == 0 || type == 4 || type == 2) && Main.tileSolid[Main.tile[tileX, tileY].type] &&
|
||||
!args.Player.Group.HasPermission(Permissions.ignorekilltiledetection))
|
||||
{
|
||||
args.Player.TileKillThreshold++;
|
||||
|
|
@ -1883,7 +2038,7 @@ namespace TShockAPI
|
|||
}
|
||||
else if (TShock.Config.PvPMode == "always" && !args.TPlayer.hostile)
|
||||
{
|
||||
args.Player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!",
|
||||
args.Player.SendMessage("PvP is forced! Enable PvP or else you can't do anything!",
|
||||
Color.Red);
|
||||
}
|
||||
int lastTileX = (int) (args.Player.LastNetPosition.X/16f);
|
||||
|
|
@ -1903,13 +2058,14 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignorenoclipdetection) &&
|
||||
TSCheckNoclip(pos, args.TPlayer.width, args.TPlayer.height) && !TShock.Config.IgnoreNoClip)
|
||||
TSCheckNoclip(pos, args.TPlayer.width, args.TPlayer.height) && !TShock.Config.IgnoreNoClip
|
||||
&& !args.TPlayer.tongued)
|
||||
{
|
||||
int lastTileX = (int) (args.Player.LastNetPosition.X/16f);
|
||||
int lastTileY = (int) (args.Player.LastNetPosition.Y/16f);
|
||||
int lastTileX = (int)(args.Player.LastNetPosition.X / 16f);
|
||||
int lastTileY = (int)(args.Player.LastNetPosition.Y / 16f);
|
||||
if (!args.Player.Teleport(lastTileX, lastTileY + 3))
|
||||
{
|
||||
args.Player.SendMessage("You got stuck in a solid object, Sent to spawn point.");
|
||||
args.Player.SendErrorMessage("You got stuck in a solid object, Sent to spawn point.");
|
||||
args.Player.Spawn();
|
||||
}
|
||||
return true;
|
||||
|
|
@ -2005,7 +2161,7 @@ namespace TShockAPI
|
|||
|
||||
if (dmg > TShock.Config.MaxProjDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
{
|
||||
args.Player.Disable(String.Format("Projectile damage is higher than {0}", TShock.Config.MaxProjDamage));
|
||||
args.Player.Disable(String.Format("Projectile damage is higher than {0}.", TShock.Config.MaxProjDamage));
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2016,23 +2172,24 @@ namespace TShockAPI
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!TShock.Config.IgnoreProjUpdate && TShock.CheckProjectilePermission(args.Player, index, type))
|
||||
bool hasPermission = !TShock.CheckProjectilePermission(args.Player, index, type);
|
||||
if (!TShock.Config.IgnoreProjUpdate && !hasPermission)
|
||||
{
|
||||
if (type == 100)
|
||||
{ //fix for skele prime
|
||||
Log.Debug("Skeletron Prime's death laser ignored for cheat detection..");
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.Disable("Does not have projectile permission to update projectile.");
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
}
|
||||
if (type == 100)
|
||||
{ //fix for skele prime
|
||||
Log.Debug("Skeletron Prime's death laser ignored for cheat detection..");
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.Disable("Does not have projectile permission to update projectile.");
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.Player.ProjectileThreshold >= TShock.Config.ProjectileThreshold)
|
||||
{
|
||||
args.Player.Disable("Reached projectile update threshold");
|
||||
args.Player.Disable("Reached projectile update threshold.");
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2045,14 +2202,22 @@ namespace TShockAPI
|
|||
|
||||
if (!args.Player.Group.HasPermission(Permissions.ignoreprojectiledetection))
|
||||
{
|
||||
if ((type ==90) && (TShock.Config.ProjIgnoreShrapnel))// ignore shrapnel
|
||||
{
|
||||
Log.Debug("Ignoring shrapnel per config..");
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.ProjectileThreshold++;
|
||||
}
|
||||
if ((type == 90) && (TShock.Config.ProjIgnoreShrapnel))// ignore shrapnel
|
||||
{
|
||||
Log.Debug("Ignoring shrapnel per config..");
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Player.ProjectileThreshold++;
|
||||
}
|
||||
}
|
||||
|
||||
// force all explosives server-side.
|
||||
if (hasPermission && (type == 28 || type == 29 || type == 37))
|
||||
{
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
Projectile.NewProjectile(pos.X, pos.Y, vel.X, vel.Y, type, dmg, knockback);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -2088,7 +2253,7 @@ namespace TShockAPI
|
|||
|
||||
if (TShock.CheckProjectilePermission(args.Player, index, type) && type != 102 && type != 100 && !TShock.Config.IgnoreProjKill)
|
||||
{
|
||||
args.Player.Disable("Does not have projectile permission to kill projectile");
|
||||
args.Player.Disable("Does not have projectile permission to kill projectile.");
|
||||
args.Player.RemoveProjectile(ident, owner);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2136,11 +2301,6 @@ namespace TShockAPI
|
|||
|
||||
if (OnLiquidSet(tileX, tileY, liquid, lava))
|
||||
return true;
|
||||
|
||||
//The liquid was picked up.
|
||||
if (liquid == 0)
|
||||
return false;
|
||||
|
||||
if (tileX < 0 || tileX >= Main.maxTilesX || tileY < 0 || tileY >= Main.maxTilesY)
|
||||
return false;
|
||||
|
||||
|
|
@ -2152,7 +2312,7 @@ namespace TShockAPI
|
|||
|
||||
if (args.Player.TileLiquidThreshold >= TShock.Config.TileLiquidThreshold)
|
||||
{
|
||||
args.Player.Disable("Reached TileLiquid threshold");
|
||||
args.Player.Disable("Reached TileLiquid threshold.");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2161,31 +2321,51 @@ namespace TShockAPI
|
|||
{
|
||||
args.Player.TileLiquidThreshold++;
|
||||
}
|
||||
if (liquid != 0)
|
||||
{
|
||||
int bucket = 0;
|
||||
if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 206)
|
||||
{
|
||||
bucket = 1;
|
||||
}
|
||||
else if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 207)
|
||||
{
|
||||
bucket = 2;
|
||||
}
|
||||
|
||||
int bucket = 0;
|
||||
if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 206)
|
||||
{
|
||||
bucket = 1;
|
||||
}
|
||||
else if (args.TPlayer.inventory[args.TPlayer.selectedItem].type == 207)
|
||||
{
|
||||
bucket = 2;
|
||||
}
|
||||
if(lava && bucket != 2)
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading lava without holding a lava bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(lava && (!args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player)))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Using banned lava bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lava && bucket != 2 && !args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Lava Bucket", args.Player))
|
||||
{
|
||||
args.Player.Disable("Using banned lava bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
if (!lava && bucket != 1)
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Spreading water without holding a water bucket");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!lava && bucket != 1 && !args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Water Bucket", args.Player))
|
||||
{
|
||||
args.Player.Disable("Using banned water bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
if (!lava && (!args.Player.Group.HasPermission(Permissions.usebanneditem) &&
|
||||
TShock.Itembans.ItemIsBanned("Water Bucket", args.Player)))
|
||||
{
|
||||
args.Player.SendErrorMessage("You do not have permission to perform this action.");
|
||||
args.Player.Disable("Using banned water bucket without permissions");
|
||||
args.Player.SendTileSquare(tileX, tileY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (TShock.CheckTilePermission(args.Player, tileX, tileY))
|
||||
|
|
@ -2461,6 +2641,11 @@ namespace TShockAPI
|
|||
if (OnItemDrop(id, pos, vel, stacks, prefix, type))
|
||||
return true;
|
||||
|
||||
// player is attempting to crash clients
|
||||
if (type < -24 || type >= Main.maxItemTypes)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (type == 0) //Item removed, let client do this to prevent item duplication client side
|
||||
{
|
||||
return false;
|
||||
|
|
@ -2521,9 +2706,9 @@ namespace TShockAPI
|
|||
if (TShock.Players[id] == null)
|
||||
return true;
|
||||
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap) && id != args.Player.Index)
|
||||
{
|
||||
args.Player.Disable(String.Format("Player damage exceeded {0}", TShock.Config.MaxDamage ) );
|
||||
args.Player.Disable(String.Format("Player damage exceeded {0}.", TShock.Config.MaxDamage));
|
||||
args.Player.SendData(PacketTypes.PlayerHp, "", id);
|
||||
args.Player.SendData(PacketTypes.PlayerUpdate, "", id);
|
||||
return true;
|
||||
|
|
@ -2576,7 +2761,7 @@ namespace TShockAPI
|
|||
|
||||
if (dmg > TShock.Config.MaxDamage && !args.Player.Group.HasPermission(Permissions.ignoredamagecap))
|
||||
{
|
||||
args.Player.Disable(String.Format("NPC damage exceeded {0}", TShock.Config.MaxDamage ) );
|
||||
args.Player.Disable(String.Format("NPC damage exceeded {0}.", TShock.Config.MaxDamage ) );
|
||||
args.Player.SendData(PacketTypes.NpcUpdate, "", id);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2589,7 +2774,7 @@ namespace TShockAPI
|
|||
|
||||
if (Main.npc[id].townNPC && !args.Player.Group.HasPermission(Permissions.movenpc))
|
||||
{
|
||||
args.Player.SendMessage( "You don't have permission to move the NPC", Color.Yellow);
|
||||
args.Player.SendMessage( "You don't have permission to move this NPC.", Color.Yellow);
|
||||
args.Player.SendData(PacketTypes.NpcUpdate, "", id);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2756,7 +2941,7 @@ namespace TShockAPI
|
|||
break;
|
||||
}
|
||||
|
||||
TShock.Utils.SendLogs(string.Format("{0} summoned {1}", args.Player.Name, boss), Color.Red);
|
||||
TShock.Utils.SendLogs(string.Format("{0} summoned {1}", args.Player.Name, boss), Color.PaleVioletRed, args.Player);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
|
@ -25,16 +26,52 @@ namespace TShockAPI
|
|||
{
|
||||
// NOTE: Using a const still suffers from needing to recompile to change the default
|
||||
// ideally we would use a static but this means it can't be used for the default parameter :(
|
||||
public const string defaultChatColor = "255.255.255";
|
||||
/// <summary>
|
||||
/// Default chat color.
|
||||
/// </summary>
|
||||
public const string defaultChatColor = "255,255,255";
|
||||
|
||||
/// <summary>
|
||||
/// List of permissions available to the group.
|
||||
/// </summary>
|
||||
public readonly List<string> permissions = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// List of permissions that the group is explicitly barred from.
|
||||
/// </summary>
|
||||
public readonly List<string> negatedpermissions = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// The group's name.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The group that this group inherits permissions from.
|
||||
/// </summary>
|
||||
public Group Parent { get; set; }
|
||||
public int Order { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The chat prefix for this group.
|
||||
/// </summary>
|
||||
public string Prefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The chat suffix for this group.
|
||||
/// </summary>
|
||||
public string Suffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the parent, not particularly sure why this is here.
|
||||
/// We can use group.Parent.Name and not have this second reference.
|
||||
/// This was added for rest, so a discussion with Shank is necessary.
|
||||
/// </summary>
|
||||
public string ParentName { get { return (null == Parent) ? "" : Parent.Name; } }
|
||||
|
||||
/// <summary>
|
||||
/// The chat color of the group.
|
||||
/// Returns "255255255", sets "255,255,255"
|
||||
/// </summary>
|
||||
public string ChatColor
|
||||
{
|
||||
get { return string.Format("{0}{1}{2}", R.ToString("X2"), G.ToString("X2"), B.ToString("X2")); }
|
||||
|
|
@ -58,6 +95,9 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The permissions of the user in string form.
|
||||
/// </summary>
|
||||
public string Permissions
|
||||
{
|
||||
get
|
||||
|
|
@ -75,6 +115,9 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The permissions of this group and all that it inherits from.
|
||||
/// </summary>
|
||||
public List<string> TotalPermissions
|
||||
{
|
||||
get
|
||||
|
|
@ -125,29 +168,55 @@ namespace TShockAPI
|
|||
Permissions = permissions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if a group has a specified permission.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to check.</param>
|
||||
/// <returns>Returns true if the user has that permission.</returns>
|
||||
public virtual bool HasPermission(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(permission))
|
||||
return true;
|
||||
|
||||
var cur = this;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
if (String.IsNullOrEmpty(permission) || RealHasPermission(permission))
|
||||
{
|
||||
if (cur.negatedpermissions.Contains(permission))
|
||||
return false;
|
||||
if (cur.permissions.Contains(permission))
|
||||
return true;
|
||||
if (traversed.Contains(cur))
|
||||
return true;
|
||||
}
|
||||
string[] nodes = permission.Split('.');
|
||||
for (int i = nodes.Length - 1; i >= 0; i--)
|
||||
{
|
||||
nodes[i] = "*";
|
||||
if (RealHasPermission(String.Join(".", nodes, 0, i + 1)))
|
||||
{
|
||||
throw new Exception("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
return true;
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private bool RealHasPermission(string permission)
|
||||
{
|
||||
if (string.IsNullOrEmpty(permission))
|
||||
return true;
|
||||
|
||||
var cur = this;
|
||||
var traversed = new List<Group>();
|
||||
while (cur != null)
|
||||
{
|
||||
if (cur.negatedpermissions.Contains(permission))
|
||||
return false;
|
||||
if (cur.permissions.Contains(permission))
|
||||
return true;
|
||||
if (traversed.Contains(cur))
|
||||
{
|
||||
throw new InvalidOperationException("Infinite group parenting ({0})".SFormat(cur.Name));
|
||||
}
|
||||
traversed.Add(cur);
|
||||
cur = cur.Parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to negate.</param>
|
||||
public void NegatePermission(string permission)
|
||||
{
|
||||
// Avoid duplicates
|
||||
|
|
@ -158,6 +227,10 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a permission to the list of permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission to add.</param>
|
||||
public void AddPermission(string permission)
|
||||
{
|
||||
if (permission.StartsWith("!"))
|
||||
|
|
@ -173,6 +246,11 @@ namespace TShockAPI
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the permission list and sets it to the list provided,
|
||||
/// will parse "!permssion" and add it to the negated permissions.
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
public void SetPermission(List<string> permission)
|
||||
{
|
||||
permissions.Clear();
|
||||
|
|
@ -180,6 +258,11 @@ namespace TShockAPI
|
|||
permission.ForEach(p => AddPermission(p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Will remove a permission from the respective list,
|
||||
/// where "!permission" will remove a negated permission.
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
public void RemovePermission(string permission)
|
||||
{
|
||||
if (permission.StartsWith("!"))
|
||||
|
|
@ -189,8 +272,31 @@ namespace TShockAPI
|
|||
}
|
||||
permissions.Remove(permission);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns all fields of this instance to another.
|
||||
/// </summary>
|
||||
/// <param name="otherGroup">The other instance.</param>
|
||||
public void AssignTo(Group otherGroup)
|
||||
{
|
||||
otherGroup.Name = Name;
|
||||
otherGroup.Parent = Parent;
|
||||
otherGroup.Prefix = Prefix;
|
||||
otherGroup.Suffix = Suffix;
|
||||
otherGroup.R = R;
|
||||
otherGroup.G = G;
|
||||
otherGroup.B = B;
|
||||
otherGroup.Permissions = Permissions;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return this.Name;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This class is the SuperAdminGroup, which has access to everything.
|
||||
/// </summary>
|
||||
public class SuperAdminGroup : Group
|
||||
{
|
||||
public SuperAdminGroup()
|
||||
|
|
@ -203,9 +309,14 @@ namespace TShockAPI
|
|||
Suffix = TShock.Config.SuperAdminChatSuffix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override to allow access to everything.
|
||||
/// </summary>
|
||||
/// <param name="permission">The permission</param>
|
||||
/// <returns>True</returns>
|
||||
public override bool HasPermission(string permission)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,11 +15,11 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,25 +15,29 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TShockDBEditor;
|
||||
|
||||
namespace TShockDBEditor
|
||||
namespace TShockAPI.Hooks
|
||||
{
|
||||
static class Program
|
||||
public class ReloadEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
public TSPlayer Player { get; set; }
|
||||
public ReloadEventArgs(TSPlayer ply)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new TShockDBEditor());
|
||||
Player = ply;
|
||||
}
|
||||
}
|
||||
|
||||
public class GeneralHooks
|
||||
{
|
||||
public delegate void ReloadEventD(ReloadEventArgs e);
|
||||
public static event ReloadEventD ReloadEvent;
|
||||
|
||||
public static void OnReloadEvent(TSPlayer ply)
|
||||
{
|
||||
if(ReloadEvent == null)
|
||||
return;
|
||||
|
||||
ReloadEvent(new ReloadEventArgs(ply));
|
||||
}
|
||||
}
|
||||
}
|
||||
98
TShockAPI/Hooks/PlayerHooks.cs
Normal file
98
TShockAPI/Hooks/PlayerHooks.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TShockAPI.Hooks
|
||||
{
|
||||
public class PlayerPostLoginEventArgs
|
||||
{
|
||||
public TSPlayer Player { get; set; }
|
||||
public PlayerPostLoginEventArgs(TSPlayer ply)
|
||||
{
|
||||
Player = ply;
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerPreLoginEventArgs : HandledEventArgs
|
||||
{
|
||||
public TSPlayer Player { get; set; }
|
||||
public string LoginName { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
public class PlayerCommandEventArgs : HandledEventArgs
|
||||
{
|
||||
public TSPlayer Player { get; set; }
|
||||
public string CommandName { get; set; }
|
||||
public string CommandText { get; set; }
|
||||
public List<string> Parameters { get; set; }
|
||||
}
|
||||
|
||||
public static class PlayerHooks
|
||||
{
|
||||
public delegate void PlayerPostLoginD(PlayerPostLoginEventArgs e);
|
||||
public static event PlayerPostLoginD PlayerPostLogin;
|
||||
|
||||
public delegate void PlayerPreLoginD(PlayerPreLoginEventArgs e);
|
||||
public static event PlayerPreLoginD PlayerPreLogin;
|
||||
|
||||
public delegate void PlayerCommandD(PlayerCommandEventArgs e);
|
||||
public static event PlayerCommandD PlayerCommand;
|
||||
|
||||
public static void OnPlayerPostLogin(TSPlayer ply)
|
||||
{
|
||||
if(PlayerPostLogin == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerPostLoginEventArgs args = new PlayerPostLoginEventArgs(ply);
|
||||
PlayerPostLogin(args);
|
||||
}
|
||||
|
||||
public static bool OnPlayerCommand(TSPlayer player, string cmdName, string cmdText, List<string> args)
|
||||
{
|
||||
if (PlayerCommand == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
PlayerCommandEventArgs playerCommandEventArgs = new PlayerCommandEventArgs()
|
||||
{
|
||||
Player = player,
|
||||
CommandName = cmdName,
|
||||
CommandText = cmdText,
|
||||
Parameters = args
|
||||
|
||||
};
|
||||
PlayerCommand(playerCommandEventArgs);
|
||||
return playerCommandEventArgs.Handled;
|
||||
}
|
||||
|
||||
public static bool OnPlayerPreLogin(TSPlayer ply, string name, string pass)
|
||||
{
|
||||
if (PlayerPreLogin == null)
|
||||
return false;
|
||||
|
||||
var args = new PlayerPreLoginEventArgs {Player = ply, LoginName = name, Password = pass};
|
||||
PlayerPreLogin(args);
|
||||
return args.Handled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
|
@ -72,6 +73,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Data(String format, params String[] args)
|
||||
{
|
||||
Data(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
|
|
@ -81,6 +92,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Error(String format, params String[] args)
|
||||
{
|
||||
Error(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
|
|
@ -93,6 +114,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an error to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void ConsoleError(String format, params String[] args)
|
||||
{
|
||||
ConsoleError(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a warning to the log file.
|
||||
/// </summary>
|
||||
|
|
@ -102,6 +133,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Warning);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a warning to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Warn(String format, params String[] args)
|
||||
{
|
||||
Warn(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file.
|
||||
/// </summary>
|
||||
|
|
@ -111,6 +152,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Info(String format, params String[] args)
|
||||
{
|
||||
Info(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file. Also outputs to the console.
|
||||
/// </summary>
|
||||
|
|
@ -123,6 +174,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes an informative string to the log file. Also outputs to the console.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void ConsoleInfo(String format, params String[] args)
|
||||
{
|
||||
ConsoleInfo(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a debug string to the log file.
|
||||
/// </summary>
|
||||
|
|
@ -132,6 +193,16 @@ namespace TShockAPI
|
|||
Write(message, LogLevel.Debug);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a debug string to the log file.
|
||||
/// </summary>
|
||||
/// <param name="format">The format of the message to be written.</param>
|
||||
/// <param name="args">The format arguments.</param>
|
||||
public static void Debug(String format, params String[] args)
|
||||
{
|
||||
Debug(String.Format(format, args));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects that are being used.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
using System.Text;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Streams;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -121,24 +122,24 @@ namespace TShockAPI
|
|||
|
||||
public bool Flush(ServerSock socket)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (socket == null || !socket.active)
|
||||
return false;
|
||||
try
|
||||
{
|
||||
if (socket == null || !socket.active)
|
||||
return false;
|
||||
|
||||
if (buffers[socket.whoAmI].Count < 1)
|
||||
return false;
|
||||
if (buffers[socket.whoAmI].Count < 1)
|
||||
return false;
|
||||
|
||||
byte[] buff = buffers[socket.whoAmI].GetBytes(BytesPerUpdate);
|
||||
if (buff == null)
|
||||
return false;
|
||||
byte[] buff = buffers[socket.whoAmI].GetBytes(BytesPerUpdate);
|
||||
if (buff == null)
|
||||
return false;
|
||||
|
||||
if (SendBytes(socket, buff))
|
||||
{
|
||||
buffers[socket.whoAmI].Pop(buff.Length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (SendBytes(socket, buff))
|
||||
{
|
||||
buffers[socket.whoAmI].Pop(buff.Length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.ConsoleError(e.ToString());
|
||||
|
|
@ -200,7 +201,14 @@ namespace TShockAPI
|
|||
}
|
||||
catch (SocketException e)
|
||||
{
|
||||
Log.Warn(e.ToString());
|
||||
switch ((uint)e.ErrorCode)
|
||||
{
|
||||
case 0x80004005:
|
||||
break;
|
||||
default:
|
||||
Log.Warn(e.ToString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
|
|
|||
316
TShockAPI/PaginationTools.cs
Normal file
316
TShockAPI/PaginationTools.cs
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public static class PaginationTools
|
||||
{
|
||||
public delegate Tuple<string, Color> LineFormatterDelegate(object lineData, int lineIndex, int pageNumber);
|
||||
|
||||
#region [Nested: Settings Class]
|
||||
public class Settings
|
||||
{
|
||||
public bool IncludeHeader { get; set; }
|
||||
|
||||
private string headerFormat;
|
||||
public string HeaderFormat
|
||||
{
|
||||
get { return this.headerFormat; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
this.headerFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color HeaderTextColor { get; set; }
|
||||
public bool IncludeFooter { get; set; }
|
||||
|
||||
private string footerFormat;
|
||||
public string FooterFormat
|
||||
{
|
||||
get { return this.footerFormat; }
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
this.footerFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Color FooterTextColor { get; set; }
|
||||
public string NothingToDisplayString { get; set; }
|
||||
public LineFormatterDelegate LineFormatter { get; set; }
|
||||
public Color LineTextColor { get; set; }
|
||||
|
||||
private int maxLinesPerPage;
|
||||
|
||||
public int MaxLinesPerPage
|
||||
{
|
||||
get { return this.maxLinesPerPage; }
|
||||
set
|
||||
{
|
||||
if (value <= 0)
|
||||
throw new ArgumentException("The value has to be greater than zero.");
|
||||
|
||||
this.maxLinesPerPage = value;
|
||||
}
|
||||
}
|
||||
|
||||
private int pageLimit;
|
||||
|
||||
public int PageLimit
|
||||
{
|
||||
get { return this.pageLimit; }
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
throw new ArgumentException("The value has to be greater than or equal to zero.");
|
||||
|
||||
this.pageLimit = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Settings()
|
||||
{
|
||||
this.IncludeHeader = true;
|
||||
this.headerFormat = "Page {0} of {1}";
|
||||
this.HeaderTextColor = Color.Green;
|
||||
this.IncludeFooter = true;
|
||||
this.footerFormat = "Type /<command> {0} for more.";
|
||||
this.FooterTextColor = Color.Yellow;
|
||||
this.NothingToDisplayString = null;
|
||||
this.LineFormatter = null;
|
||||
this.LineTextColor = Color.White;
|
||||
this.maxLinesPerPage = 4;
|
||||
this.pageLimit = 0;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static void SendPage(
|
||||
TSPlayer player, int pageNumber, IEnumerable dataToPaginate, int dataToPaginateCount, Settings settings = null)
|
||||
{
|
||||
if (settings == null)
|
||||
settings = new Settings();
|
||||
|
||||
if (dataToPaginateCount == 0)
|
||||
{
|
||||
if (settings.NothingToDisplayString != null)
|
||||
{
|
||||
if (player is TSServerPlayer)
|
||||
{
|
||||
player.SendSuccessMessage(settings.NothingToDisplayString);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.SendMessage(settings.NothingToDisplayString, settings.HeaderTextColor);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int pageCount = ((dataToPaginateCount - 1) / settings.MaxLinesPerPage) + 1;
|
||||
if (settings.PageLimit > 0 && pageCount > settings.PageLimit)
|
||||
pageCount = settings.PageLimit;
|
||||
if (pageNumber > pageCount)
|
||||
pageNumber = pageCount;
|
||||
|
||||
if (settings.IncludeHeader)
|
||||
{
|
||||
if (player is TSServerPlayer)
|
||||
{
|
||||
player.SendSuccessMessage(string.Format(settings.HeaderFormat, pageNumber, pageCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.SendMessage(string.Format(settings.HeaderFormat, pageNumber, pageCount), settings.HeaderTextColor);
|
||||
}
|
||||
}
|
||||
|
||||
int listOffset = (pageNumber - 1) * settings.MaxLinesPerPage;
|
||||
int offsetCounter = 0;
|
||||
int lineCounter = 0;
|
||||
foreach (object lineData in dataToPaginate)
|
||||
{
|
||||
if (lineData == null)
|
||||
continue;
|
||||
if (offsetCounter++ < listOffset)
|
||||
continue;
|
||||
if (lineCounter++ == settings.MaxLinesPerPage)
|
||||
break;
|
||||
|
||||
string lineMessage;
|
||||
Color lineColor = settings.LineTextColor;
|
||||
if (lineData is Tuple<string, Color>)
|
||||
{
|
||||
var lineFormat = (Tuple<string, Color>)lineData;
|
||||
lineMessage = lineFormat.Item1;
|
||||
lineColor = lineFormat.Item2;
|
||||
}
|
||||
else if (settings.LineFormatter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Tuple<string, Color> lineFormat = settings.LineFormatter(lineData, offsetCounter, pageNumber);
|
||||
if (lineFormat == null)
|
||||
continue;
|
||||
|
||||
lineMessage = lineFormat.Item1;
|
||||
lineColor = lineFormat.Item2;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"The method referenced by LineFormatter has thrown an exception. See inner exception for details.", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lineMessage = lineData.ToString();
|
||||
}
|
||||
|
||||
if (lineMessage != null)
|
||||
{
|
||||
if (player is TSServerPlayer)
|
||||
{
|
||||
Console.WriteLine(lineMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.SendMessage(lineMessage, lineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lineCounter == 0)
|
||||
{
|
||||
if (settings.NothingToDisplayString != null)
|
||||
{
|
||||
if (player is TSServerPlayer)
|
||||
{
|
||||
player.SendSuccessMessage(settings.NothingToDisplayString);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.SendMessage(settings.NothingToDisplayString, settings.HeaderTextColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (settings.IncludeFooter && pageNumber + 1 <= pageCount)
|
||||
{
|
||||
if (player is TSServerPlayer)
|
||||
{
|
||||
player.SendInfoMessage(string.Format(settings.FooterFormat, pageNumber + 1, pageNumber, pageCount));
|
||||
}
|
||||
else
|
||||
{
|
||||
player.SendMessage(string.Format(settings.FooterFormat, pageNumber + 1, pageNumber, pageCount), settings.FooterTextColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SendPage(TSPlayer player, int pageNumber, IList dataToPaginate, Settings settings = null)
|
||||
{
|
||||
PaginationTools.SendPage(player, pageNumber, dataToPaginate, dataToPaginate.Count, settings);
|
||||
}
|
||||
|
||||
public static List<string> BuildLinesFromTerms(
|
||||
IEnumerable terms, Func<object, string> termFormatter = null, string separator = ", ", int maxCharsPerLine = 80)
|
||||
{
|
||||
List<string> lines = new List<string>();
|
||||
StringBuilder lineBuilder = new StringBuilder();
|
||||
foreach (object term in terms)
|
||||
{
|
||||
if (term == null && termFormatter == null)
|
||||
continue;
|
||||
|
||||
string termString;
|
||||
if (termFormatter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
termString = termFormatter(term);
|
||||
|
||||
if (termString == null)
|
||||
continue;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"The method represented by termFormatter has thrown an exception. See inner exception for details.", ex);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
termString = term.ToString();
|
||||
}
|
||||
|
||||
bool goesOnNextLine = (lineBuilder.Length + termString.Length > maxCharsPerLine);
|
||||
if (!goesOnNextLine)
|
||||
{
|
||||
if (lineBuilder.Length > 0)
|
||||
lineBuilder.Append(separator);
|
||||
lineBuilder.Append(termString);
|
||||
}
|
||||
else
|
||||
{
|
||||
// A separator should always be at the end of a line as we know it is followed by another line.
|
||||
lineBuilder.Append(separator);
|
||||
lines.Add(lineBuilder.ToString());
|
||||
lineBuilder.Clear();
|
||||
|
||||
lineBuilder.Append(termString);
|
||||
}
|
||||
}
|
||||
if (lineBuilder.Length > 0)
|
||||
lines.Add(lineBuilder.ToString());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static bool TryParsePageNumber(
|
||||
List<string> commandParameters, int expectedParamterIndex, TSPlayer errorMessageReceiver, out int pageNumber)
|
||||
{
|
||||
pageNumber = 1;
|
||||
if (commandParameters.Count <= expectedParamterIndex)
|
||||
return true;
|
||||
|
||||
string pageNumberRaw = commandParameters[expectedParamterIndex];
|
||||
if (!int.TryParse(pageNumberRaw, out pageNumber) || pageNumber < 1)
|
||||
{
|
||||
if (errorMessageReceiver != null)
|
||||
errorMessageReceiver.SendErrorMessage(string.Format("\"{0}\" is not a valid page number.", pageNumberRaw));
|
||||
|
||||
pageNumber = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -73,7 +74,7 @@ namespace TShockAPI
|
|||
[Description("Allows you to bypass the max slots for up to 5 slots above your max")] public static readonly string
|
||||
reservedslot;
|
||||
|
||||
[Description("User is notified when an update is available")] public static readonly string maintenance;
|
||||
[Description("User is notified when an update is available, user can turn off / restart the server.")] public static readonly string maintenance;
|
||||
|
||||
[Description("User can kick others")] public static readonly string kick;
|
||||
|
||||
|
|
@ -129,7 +130,7 @@ namespace TShockAPI
|
|||
|
||||
[Description("User can change the homes of NPCs.")] public static readonly string movenpc;
|
||||
|
||||
[Description("Users can stop people from TPing to them")] public static readonly string tpallow;
|
||||
[Description("Users can stop people from teleporting to them")] public static readonly string tpallow;
|
||||
|
||||
[Description("Users can tp to anyone")] public static readonly string tpall;
|
||||
|
||||
|
|
@ -149,9 +150,9 @@ namespace TShockAPI
|
|||
|
||||
[Description("User can talk in third person")] public static readonly string cantalkinthird;
|
||||
|
||||
[Description("Bypass Server Side Inventory checks")] public static readonly string bypassinventorychecks;
|
||||
[Description("Bypass server side inventory checks")] public static readonly string bypassinventorychecks;
|
||||
|
||||
[Description("Allow unrestricted Send Tile Square usage, for client side world editing")] public static readonly
|
||||
[Description("Allow unrestricted SendTileSquare usage, for client side world editing.")] public static readonly
|
||||
string allowclientsideworldedit;
|
||||
|
||||
[Description("User can summon bosses using items")]
|
||||
|
|
@ -166,18 +167,22 @@ namespace TShockAPI
|
|||
[Description("User can save all the players SSI state.")]
|
||||
public static readonly string savessi;
|
||||
|
||||
[Description("User can use rest api calls.")]
|
||||
public static readonly string restapi;
|
||||
[Description("User can force the server to Christmas mode.")] public static readonly string xmas;
|
||||
|
||||
static Permissions()
|
||||
[Description("User can use /home.")] public static readonly string home;
|
||||
|
||||
[Description("User can use /spawn.")] public static readonly string spawn;
|
||||
|
||||
[Description("User can elevate other users' groups temporarily.")] public static readonly string settempgroup;
|
||||
|
||||
[Description("User can download updates to plugins that are currently running.")] public static readonly string updateplugins;
|
||||
|
||||
static Permissions()
|
||||
{
|
||||
foreach (var field in typeof (Permissions).GetFields())
|
||||
{
|
||||
field.SetValue(null, field.Name);
|
||||
}
|
||||
|
||||
//Backwards compatability.
|
||||
restapi = "api";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -189,7 +194,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (Commands.ChatCommands.Count < 1)
|
||||
Commands.InitCommands();
|
||||
return Commands.ChatCommands.Where(c => c.Permission == perm).ToList();
|
||||
return Commands.ChatCommands.Where(c => c.Permissions.Contains(perm)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
87
TShockAPI/PluginUpdater/PluginUpdaterThread.cs
Normal file
87
TShockAPI/PluginUpdater/PluginUpdaterThread.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI.PluginUpdater
|
||||
{
|
||||
class PluginUpdaterThread
|
||||
{
|
||||
private TSPlayer invoker;
|
||||
public PluginUpdaterThread(TSPlayer player)
|
||||
{
|
||||
invoker = player;
|
||||
PluginVersionCheck.PluginUpdate += PluginUpdate;
|
||||
HandleUpdate();
|
||||
}
|
||||
|
||||
private void HandleUpdate()
|
||||
{
|
||||
foreach(PluginContainer cont in ProgramServer.Plugins)
|
||||
new Thread(PluginVersionCheck.CheckPlugin).Start(cont.Plugin);
|
||||
}
|
||||
|
||||
private int Updates = 0;
|
||||
private void PluginUpdate(UpdateArgs args)
|
||||
{
|
||||
Updates++;
|
||||
if(args.Success && String.IsNullOrEmpty(args.Error))
|
||||
{
|
||||
invoker.SendSuccessMessage(String.Format("{0} was downloaded successfully.", args.Plugin.Name));
|
||||
}
|
||||
else if(args.Success)
|
||||
{
|
||||
invoker.SendSuccessMessage(String.Format("{0} was skipped. Reason: {1}", args.Plugin.Name, args.Error));
|
||||
}
|
||||
else
|
||||
{
|
||||
invoker.SendSuccessMessage(String.Format("{0} failed to downloaded. Error: {1}", args.Plugin.Name, args.Error));
|
||||
}
|
||||
|
||||
if(Updates >= Terraria.ProgramServer.Plugins.Count)
|
||||
{
|
||||
PluginVersionCheck.PluginUpdate -= PluginUpdate;
|
||||
|
||||
invoker.SendSuccessMessage("All plugins have been downloaded. Now copying them to the plugin folder...");
|
||||
|
||||
string folder = Path.Combine(TShock.SavePath, "UpdatedPlugins");
|
||||
string dest = Path.Combine(TShock.SavePath, "..", "ServerPlugins");
|
||||
|
||||
foreach (string dir in Directory.GetDirectories(folder, "*", System.IO.SearchOption.AllDirectories))
|
||||
{
|
||||
string new_folder = dest + dir.Substring(folder.Length);
|
||||
if (!Directory.Exists(new_folder))
|
||||
Directory.CreateDirectory(new_folder);
|
||||
}
|
||||
|
||||
foreach (string file_name in Directory.GetFiles(folder, "*.*", System.IO.SearchOption.AllDirectories))
|
||||
{
|
||||
TSPlayer.Server.SendSuccessMessage(String.Format("Copied {0}", file_name));
|
||||
File.Copy(file_name, dest + file_name.Substring(folder.Length), true);
|
||||
}
|
||||
|
||||
|
||||
Directory.Delete(folder, true);
|
||||
|
||||
invoker.SendSuccessMessage("All plugins have been processed. Restart the server to have access to the new plugins.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
TShockAPI/PluginUpdater/PluginVersionCheck.cs
Normal file
127
TShockAPI/PluginUpdater/PluginVersionCheck.cs
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using JsonLoader;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace TShockAPI.PluginUpdater
|
||||
{
|
||||
public class PluginVersionCheck
|
||||
{
|
||||
public delegate void PluginUpdateD(UpdateArgs e);
|
||||
public static event PluginUpdateD PluginUpdate;
|
||||
public static void OnPluginUpdate(UpdateArgs args)
|
||||
{
|
||||
if (PluginUpdate == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PluginUpdate(args);
|
||||
}
|
||||
|
||||
public static void CheckPlugin(object p)
|
||||
{
|
||||
TerrariaPlugin plugin = (TerrariaPlugin)p;
|
||||
UpdateArgs args = new UpdateArgs {Plugin = plugin, Success = true, Error = ""};
|
||||
List<string> files = new List<string>();
|
||||
|
||||
try
|
||||
{
|
||||
if (!String.IsNullOrEmpty(plugin.UpdateURL))
|
||||
{
|
||||
var request = HttpWebRequest.Create(plugin.UpdateURL);
|
||||
VersionInfo vi;
|
||||
|
||||
request.Timeout = 5000;
|
||||
using (var response = request.GetResponse())
|
||||
{
|
||||
using (var reader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
vi = JsonConvert.DeserializeObject<VersionInfo>(reader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
|
||||
System.Version v = System.Version.Parse((vi.version.ToString()));
|
||||
|
||||
if (!v.Equals(plugin.Version))
|
||||
{
|
||||
DownloadPackage pkg;
|
||||
request = HttpWebRequest.Create(vi.url);
|
||||
|
||||
request.Timeout = 5000;
|
||||
using (var response = request.GetResponse())
|
||||
{
|
||||
using (var reader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
pkg = JsonConvert.DeserializeObject<DownloadPackage>(reader.ReadToEnd());
|
||||
}
|
||||
}
|
||||
|
||||
foreach (PluginFile f in pkg.files)
|
||||
{
|
||||
using (WebClient Client = new WebClient())
|
||||
{
|
||||
string dir = Path.Combine(TShock.SavePath, "UpdatedPlugins");
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
Client.DownloadFile(f.url,
|
||||
Path.Combine(dir, f.destination));
|
||||
|
||||
files.Add(Path.Combine(dir, f.destination));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Error = "Plugin is up to date.";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.Error = "Plugin has no updater recorded.";
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
args.Success = false;
|
||||
args.Error = e.Message;
|
||||
if(files.Count > 0)
|
||||
{
|
||||
foreach(string s in files)
|
||||
{
|
||||
File.Delete(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OnPluginUpdate(args);
|
||||
}
|
||||
}
|
||||
|
||||
public class UpdateArgs
|
||||
{
|
||||
public TerrariaPlugin Plugin { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public string Error { get; set; }
|
||||
}
|
||||
}
|
||||
87
TShockAPI/PluginUpdater/VersionInfo.cs
Normal file
87
TShockAPI/PluginUpdater/VersionInfo.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace JsonLoader
|
||||
{
|
||||
class VersionInfo
|
||||
{
|
||||
public Version version;
|
||||
public string url;
|
||||
}
|
||||
|
||||
public class Version
|
||||
{
|
||||
public int Major;
|
||||
public int Minor;
|
||||
public int Build;
|
||||
public int Revision;
|
||||
public int MajorRevision;
|
||||
public int MinorRevision;
|
||||
|
||||
public Version()
|
||||
{
|
||||
SetVersion(0,0,0,0);
|
||||
}
|
||||
|
||||
public Version(int m)
|
||||
{
|
||||
SetVersion(m, 0, 0, 0);
|
||||
}
|
||||
|
||||
public Version(int ma, int mi)
|
||||
{
|
||||
SetVersion(ma, mi, 0, 0);
|
||||
}
|
||||
|
||||
public Version(int ma, int mi, int b)
|
||||
{
|
||||
SetVersion(ma, mi, b, 0);
|
||||
}
|
||||
|
||||
public Version(int ma, int mi, int b, int r)
|
||||
{
|
||||
SetVersion(ma, mi, b, r);
|
||||
}
|
||||
|
||||
private void SetVersion(int ma, int mi, int b, int r)
|
||||
{
|
||||
Major = ma;
|
||||
Minor = mi;
|
||||
Build = b;
|
||||
Revision = r;
|
||||
}
|
||||
|
||||
public string ToString()
|
||||
{
|
||||
return String.Format("{0}.{1}.{2}.{3}", Major, Minor, Build, Revision);
|
||||
}
|
||||
}
|
||||
|
||||
class DownloadPackage
|
||||
{
|
||||
public List<PluginFile> files;
|
||||
}
|
||||
|
||||
class PluginFile
|
||||
{
|
||||
public string url;
|
||||
public string destination = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ using System.Runtime.InteropServices;
|
|||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Nyx Team")]
|
||||
[assembly: AssemblyProduct("TShockAPI")]
|
||||
[assembly: AssemblyCopyright("Copyright © Nyx Team 2012")]
|
||||
[assembly: AssemblyCopyright("Copyright © Nyx Team 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
|
@ -48,5 +49,5 @@ using System.Runtime.InteropServices;
|
|||
// Build Number
|
||||
// MMdd of the build
|
||||
|
||||
[assembly: AssemblyVersion("3.9.1.0526")]
|
||||
[assembly: AssemblyFileVersion("3.9.1.0526")]
|
||||
[assembly: AssemblyVersion("4.1.0.0419")]
|
||||
[assembly: AssemblyFileVersion("4.1.0.0419")]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
|
|||
5
TShockAPI/Resources.Designer.cs
generated
5
TShockAPI/Resources.Designer.cs
generated
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -27,9 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace TShockAPI {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -38,6 +39,15 @@ namespace Rests
|
|||
/// <returns>Response object or null to not handle request</returns>
|
||||
public delegate object RestCommandD(RestVerbs verbs, IParameterCollection parameters);
|
||||
|
||||
/// <summary>
|
||||
/// Secure Rest command delegate including token data.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters in the url</param>
|
||||
/// <param name="verbs">{x} in urltemplate</param>
|
||||
/// <param name="tokenData">The data of stored for the provided token.</param>
|
||||
/// <returns>Response object or null to not handle request</returns>
|
||||
public delegate object SecureRestCommandD(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData);
|
||||
|
||||
public class Rest : IDisposable
|
||||
{
|
||||
private readonly List<RestCommand> commands = new List<RestCommand>();
|
||||
|
|
@ -125,6 +135,11 @@ namespace Rests
|
|||
return;
|
||||
|
||||
var str = JsonConvert.SerializeObject(obj, Formatting.Indented);
|
||||
var jsonp = e.Request.Parameters["jsonp"];
|
||||
if (!string.IsNullOrWhiteSpace(jsonp))
|
||||
{
|
||||
str = string.Format("{0}({1});", jsonp, str);
|
||||
}
|
||||
e.Response.Connection.Type = ConnectionType.Close;
|
||||
e.Response.ContentType = new ContentTypeHeader("application/json");
|
||||
e.Response.Add(serverHeader);
|
||||
|
|
@ -165,24 +180,47 @@ namespace Rests
|
|||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return new Dictionary<string, string>
|
||||
return new RestObject("500")
|
||||
{
|
||||
{"status", "500"},
|
||||
{"error", "Internal server error."},
|
||||
{"errormsg", exception.Message},
|
||||
{"stacktrace", exception.StackTrace},
|
||||
};
|
||||
}
|
||||
return new Dictionary<string, string>
|
||||
return new RestObject("404")
|
||||
{
|
||||
{"status", "404"},
|
||||
{"error", "Specified API endpoint doesn't exist. Refer to the documentation for a list of valid endpoints."}
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
|
||||
{
|
||||
return cmd.Callback(verbs, parms);
|
||||
object result = cmd.Execute(verbs, parms);
|
||||
if (cmd.DoLog)
|
||||
Log.ConsoleInfo("Anonymous requested REST endpoint: " + BuildRequestUri(cmd, verbs, parms, false));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual string BuildRequestUri(
|
||||
RestCommand cmd, RestVerbs verbs, IParameterCollection parms, bool includeToken = true
|
||||
) {
|
||||
StringBuilder requestBuilder = new StringBuilder(cmd.UriTemplate);
|
||||
char separator = '?';
|
||||
foreach (IParameter paramImpl in parms)
|
||||
{
|
||||
Parameter param = (paramImpl as Parameter);
|
||||
if (param == null || (!includeToken && param.Name.Equals("token", StringComparison.InvariantCultureIgnoreCase)))
|
||||
continue;
|
||||
|
||||
requestBuilder.Append(separator);
|
||||
requestBuilder.Append(param.Name);
|
||||
requestBuilder.Append('=');
|
||||
requestBuilder.Append(param.Value);
|
||||
separator = '&';
|
||||
}
|
||||
|
||||
return requestBuilder.ToString();
|
||||
}
|
||||
|
||||
#region Dispose
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,8 +15,10 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using HttpServer;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
|
|
@ -26,8 +28,10 @@ namespace Rests
|
|||
public string UriTemplate { get; protected set; }
|
||||
public string UriVerbMatch { get; protected set; }
|
||||
public string[] UriVerbs { get; protected set; }
|
||||
public RestCommandD Callback { get; protected set; }
|
||||
public bool RequiresToken { get; set; }
|
||||
public virtual bool RequiresToken { get { return false; } }
|
||||
public bool DoLog { get; set; }
|
||||
|
||||
private RestCommandD callback;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
|
@ -42,8 +46,8 @@ namespace Rests
|
|||
UriVerbMatch = string.Format("^{0}$", string.Join("([^/]*)", Regex.Split(uritemplate, "\\{[^\\{\\}]*\\}")));
|
||||
var matches = Regex.Matches(uritemplate, "\\{([^\\{\\}]*)\\}");
|
||||
UriVerbs = (from Match match in matches select match.Groups[1].Value).ToArray();
|
||||
Callback = callback;
|
||||
RequiresToken = true;
|
||||
this.callback = callback;
|
||||
DoLog = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -60,5 +64,43 @@ namespace Rests
|
|||
{
|
||||
get { return UriVerbs.Length > 0; }
|
||||
}
|
||||
|
||||
public virtual object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return callback(verbs, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
public class SecureRestCommand: RestCommand
|
||||
{
|
||||
public override bool RequiresToken { get { return true; } }
|
||||
public string[] Permissions { get; set; }
|
||||
|
||||
private SecureRestCommandD callback;
|
||||
|
||||
public SecureRestCommand(string name, string uritemplate, SecureRestCommandD callback, params string[] permissions)
|
||||
: base(name, uritemplate, null)
|
||||
{
|
||||
this.callback = callback;
|
||||
Permissions = permissions;
|
||||
}
|
||||
|
||||
public SecureRestCommand(string uritemplate, SecureRestCommandD callback, params string[] permissions)
|
||||
: this(string.Empty, uritemplate, callback, permissions)
|
||||
{
|
||||
}
|
||||
|
||||
public override object Execute(RestVerbs verbs, IParameterCollection parameters)
|
||||
{
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
}
|
||||
|
||||
public object Execute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (tokenData.Equals(SecureRest.TokenData.None))
|
||||
return new RestObject("401") { Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
|
||||
return callback(verbs, parameters, tokenData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,9 +15,11 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using HttpServer;
|
||||
using Rests;
|
||||
|
|
@ -38,78 +40,140 @@ namespace TShockAPI
|
|||
public void RegisterRestfulCommands()
|
||||
{
|
||||
// Server Commands
|
||||
Rest.Register(new RestCommand("/v2/server/broadcast", ServerBroadcast));
|
||||
Rest.Register(new RestCommand("/v2/server/off", ServerOff));
|
||||
Rest.Register(new RestCommand("/v2/server/rawcmd", ServerCommand));
|
||||
Rest.Register(new RestCommand("/v2/server/status", ServerStatusV2) { RequiresToken = false });
|
||||
Rest.Register(new RestCommand("/tokentest", ServerTokenTest));
|
||||
Rest.Register(new RestCommand("/status", ServerStatus) { RequiresToken = false });
|
||||
if (TShock.Config.EnableTokenEndpointAuthentication)
|
||||
{
|
||||
Rest.Register(new SecureRestCommand("/v2/server/status", ServerStatusV2));
|
||||
Rest.Register(new SecureRestCommand("/status", ServerStatus));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/motd", ServerMotd));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/rules", ServerRules));
|
||||
}
|
||||
else
|
||||
{
|
||||
Rest.Register(new RestCommand("/v2/server/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/status", (a, b) => this.ServerStatusV2(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/motd", (a, b) => this.ServerMotd(a, b, SecureRest.TokenData.None)));
|
||||
Rest.Register(new RestCommand("/v3/server/rules", (a, b) => this.ServerRules(a, b, SecureRest.TokenData.None)));
|
||||
}
|
||||
|
||||
Rest.Register(new SecureRestCommand("/v2/server/broadcast", ServerBroadcast));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/reload", ServerReload, RestPermissions.restcfg));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/off", ServerOff, RestPermissions.restmaintenance));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/restart", ServerRestart, RestPermissions.restmaintenance));
|
||||
Rest.Register(new SecureRestCommand("/v2/server/rawcmd", ServerCommand, RestPermissions.restrawcommand));
|
||||
Rest.Register(new SecureRestCommand("/v3/server/rawcmd", ServerCommandV3, RestPermissions.restrawcommand));
|
||||
Rest.Register(new SecureRestCommand("/tokentest", ServerTokenTest));
|
||||
|
||||
// User Commands
|
||||
Rest.Register(new RestCommand("/v2/users/activelist", UserActiveListV2));
|
||||
Rest.Register(new RestCommand("/v2/users/create", UserCreateV2));
|
||||
Rest.Register(new RestCommand("/v2/users/list", UserListV2));
|
||||
Rest.Register(new RestCommand("/v2/users/read", UserInfoV2));
|
||||
Rest.Register(new RestCommand("/v2/users/destroy", UserDestroyV2));
|
||||
Rest.Register(new RestCommand("/v2/users/update", UserUpdateV2));
|
||||
Rest.Register(new SecureRestCommand("/v2/users/activelist", UserActiveListV2, RestPermissions.restviewusers));
|
||||
Rest.Register(new SecureRestCommand("/v2/users/create", UserCreateV2, RestPermissions.restmanageusers) { DoLog = false });
|
||||
Rest.Register(new SecureRestCommand("/v2/users/list", UserListV2, RestPermissions.restviewusers));
|
||||
Rest.Register(new SecureRestCommand("/v2/users/read", UserInfoV2, RestPermissions.restviewusers));
|
||||
Rest.Register(new SecureRestCommand("/v2/users/destroy", UserDestroyV2, RestPermissions.restmanageusers));
|
||||
Rest.Register(new SecureRestCommand("/v2/users/update", UserUpdateV2, RestPermissions.restmanageusers) { DoLog = false });
|
||||
|
||||
// Ban Commands
|
||||
Rest.Register(new RestCommand("/bans/create", BanCreate));
|
||||
Rest.Register(new RestCommand("/v2/bans/list", BanListV2));
|
||||
Rest.Register(new RestCommand("/v2/bans/read", BanInfoV2));
|
||||
Rest.Register(new RestCommand("/v2/bans/destroy", BanDestroyV2));
|
||||
Rest.Register(new SecureRestCommand("/bans/create", BanCreate, RestPermissions.restmanagebans));
|
||||
Rest.Register(new SecureRestCommand("/v2/bans/list", BanListV2, RestPermissions.restviewbans));
|
||||
Rest.Register(new SecureRestCommand("/v2/bans/read", BanInfoV2, RestPermissions.restviewbans));
|
||||
Rest.Register(new SecureRestCommand("/v2/bans/destroy", BanDestroyV2, RestPermissions.restmanagebans));
|
||||
|
||||
// World Commands
|
||||
Rest.Register(new RestCommand("/world/read", WorldRead));
|
||||
Rest.Register(new RestCommand("/world/meteor", WorldMeteor));
|
||||
Rest.Register(new RestCommand("/world/bloodmoon/{bool}", WorldBloodmoon));
|
||||
Rest.Register(new RestCommand("/v2/world/save", WorldSave));
|
||||
Rest.Register(new RestCommand("/v2/world/autosave/state/{bool}", WorldChangeSaveSettings));
|
||||
Rest.Register(new RestCommand("/v2/world/butcher", WorldButcher));
|
||||
Rest.Register(new SecureRestCommand("/world/read", WorldRead));
|
||||
Rest.Register(new SecureRestCommand("/world/meteor", WorldMeteor, RestPermissions.restcauseevents));
|
||||
Rest.Register(new SecureRestCommand("/world/bloodmoon/{bool}", WorldBloodmoon, RestPermissions.restcauseevents));
|
||||
Rest.Register(new SecureRestCommand("/v2/world/save", WorldSave, RestPermissions.restcfg));
|
||||
Rest.Register(new SecureRestCommand("/v2/world/autosave/state/{bool}", WorldChangeSaveSettings, RestPermissions.restcfg));
|
||||
Rest.Register(new SecureRestCommand("/v2/world/butcher", WorldButcher, RestPermissions.restbutcher));
|
||||
|
||||
// Player Commands
|
||||
Rest.Register(new RestCommand("/lists/players", PlayerList));
|
||||
Rest.Register(new RestCommand("/v2/players/list", PlayerListV2));
|
||||
Rest.Register(new RestCommand("/v2/players/read", PlayerReadV2));
|
||||
Rest.Register(new RestCommand("/v2/players/kick", PlayerKickV2));
|
||||
Rest.Register(new RestCommand("/v2/players/ban", PlayerBanV2));
|
||||
Rest.Register(new RestCommand("/v2/players/kill", PlayerKill));
|
||||
Rest.Register(new RestCommand("/v2/players/mute", PlayerMute));
|
||||
Rest.Register(new RestCommand("/v2/players/unmute", PlayerUnMute));
|
||||
Rest.Register(new SecureRestCommand("/lists/players", PlayerList));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/list", PlayerListV2));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/read", PlayerReadV2, RestPermissions.restuserinfo));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/kick", PlayerKickV2, RestPermissions.restkick));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/ban", PlayerBanV2, RestPermissions.restban, RestPermissions.restmanagebans));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/kill", PlayerKill, RestPermissions.restkill));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/mute", PlayerMute, RestPermissions.restmute));
|
||||
Rest.Register(new SecureRestCommand("/v2/players/unmute", PlayerUnMute, RestPermissions.restmute));
|
||||
|
||||
// Group Commands
|
||||
Rest.Register(new RestCommand("/v2/groups/list", GroupList));
|
||||
Rest.Register(new RestCommand("/v2/groups/read", GroupInfo));
|
||||
Rest.Register(new RestCommand("/v2/groups/destroy", GroupDestroy));
|
||||
Rest.Register(new RestCommand("/v2/groups/create", GroupCreate));
|
||||
Rest.Register(new RestCommand("/v2/groups/update", GroupUpdate));
|
||||
Rest.Register(new SecureRestCommand("/v2/groups/list", GroupList, RestPermissions.restviewgroups));
|
||||
Rest.Register(new SecureRestCommand("/v2/groups/read", GroupInfo, RestPermissions.restviewgroups));
|
||||
Rest.Register(new SecureRestCommand("/v2/groups/destroy", GroupDestroy, RestPermissions.restmanagegroups));
|
||||
Rest.Register(new SecureRestCommand("/v2/groups/create", GroupCreate, RestPermissions.restmanagegroups));
|
||||
Rest.Register(new SecureRestCommand("/v2/groups/update", GroupUpdate, RestPermissions.restmanagegroups));
|
||||
}
|
||||
|
||||
#region RestServerMethods
|
||||
|
||||
private object ServerCommand(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerCommand(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parameters["cmd"]))
|
||||
return RestMissingParam("cmd");
|
||||
|
||||
TSRestPlayer tr = new TSRestPlayer();
|
||||
Group restPlayerGroup;
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
|
||||
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup);
|
||||
Commands.HandleCommand(tr, parameters["cmd"]);
|
||||
return RestResponse(string.Join("\n", tr.GetCommandOutput()));
|
||||
}
|
||||
|
||||
private object ServerOff(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerCommandV3(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parameters["cmd"]))
|
||||
return RestMissingParam("cmd");
|
||||
|
||||
Group restPlayerGroup;
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel)
|
||||
restPlayerGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
else
|
||||
restPlayerGroup = new SuperAdminGroup();
|
||||
|
||||
TSRestPlayer tr = new TSRestPlayer(tokenData.Username, restPlayerGroup);
|
||||
Commands.HandleCommand(tr, parameters["cmd"]);
|
||||
return new RestObject()
|
||||
{
|
||||
{"response", tr.GetCommandOutput()}
|
||||
};
|
||||
}
|
||||
|
||||
private object ServerOff(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (!GetBool(parameters["confirm"], false))
|
||||
return RestInvalidParam("confirm");
|
||||
|
||||
// Inform players the server is shutting down
|
||||
var msg = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is shutting down" : parameters["message"];
|
||||
TShock.Utils.StopServer(!GetBool(parameters["nosave"], false), msg);
|
||||
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is shutting down" : parameters["message"];
|
||||
TShock.Utils.StopServer(!GetBool(parameters["nosave"], false), reason);
|
||||
|
||||
return RestResponse("The server is shutting down");
|
||||
}
|
||||
|
||||
private object ServerBroadcast(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerRestart(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (!GetBool(parameters["confirm"], false))
|
||||
return RestInvalidParam("confirm");
|
||||
|
||||
// Inform players the server is shutting down
|
||||
var reason = string.IsNullOrWhiteSpace(parameters["message"]) ? "Server is restarting" : parameters["message"];
|
||||
TShock.Utils.RestartServer(!GetBool(parameters["nosave"], false), reason);
|
||||
|
||||
return RestResponse("The server is shutting down and will attempt to restart");
|
||||
}
|
||||
|
||||
private object ServerReload(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
TShock.Utils.Reload(new TSRestPlayer(tokenData.Username, TShock.Groups.GetGroupByName(tokenData.UserGroupName)));
|
||||
|
||||
return RestResponse("Configuration, permissions, and regions reload complete. Some changes may require a server restart.");
|
||||
}
|
||||
|
||||
private object ServerBroadcast(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var msg = parameters["msg"];
|
||||
if (string.IsNullOrWhiteSpace(msg))
|
||||
|
|
@ -118,11 +182,32 @@ namespace TShockAPI
|
|||
return RestResponse("The message was broadcasted successfully");
|
||||
}
|
||||
|
||||
private object ServerStatus(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerMotd(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (TShock.Config.EnableTokenEndpointAuthentication)
|
||||
return RestError("Server settings require a token for this API call");
|
||||
string motdFilePath = Path.Combine(TShock.SavePath, "motd.txt");
|
||||
if (!File.Exists(motdFilePath))
|
||||
return this.RestError("The motd.txt was not found.", "500");
|
||||
|
||||
return new RestObject()
|
||||
{
|
||||
{"motd", File.ReadAllLines(motdFilePath)}
|
||||
};
|
||||
}
|
||||
|
||||
private object ServerRules(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
string rulesFilePath = Path.Combine(TShock.SavePath, "rules.txt");
|
||||
if (!File.Exists(rulesFilePath))
|
||||
return this.RestError("The rules.txt was not found.", "500");
|
||||
|
||||
return new RestObject()
|
||||
{
|
||||
{"rules", File.ReadAllLines(rulesFilePath)}
|
||||
};
|
||||
}
|
||||
|
||||
private object ServerStatus(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
|
||||
return new RestObject()
|
||||
{
|
||||
|
|
@ -133,18 +218,17 @@ namespace TShockAPI
|
|||
};
|
||||
}
|
||||
|
||||
private object ServerStatusV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerStatusV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (TShock.Config.EnableTokenEndpointAuthentication)
|
||||
return RestError("Server settings require a token for this API call");
|
||||
|
||||
var ret = new RestObject()
|
||||
{
|
||||
{"name", TShock.Config.ServerName},
|
||||
{"port", TShock.Config.ServerPort},
|
||||
{"playercount", Main.player.Where(p => null != p && p.active).Count()},
|
||||
{"maxplayers", TShock.Config.MaxSlots},
|
||||
{"world", Main.worldName}
|
||||
{"world", Main.worldName},
|
||||
{"uptime", (DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime).ToString(@"d'.'hh':'mm':'ss")},
|
||||
{"serverpassword", !string.IsNullOrEmpty(TShock.Config.ServerPassword)}
|
||||
};
|
||||
|
||||
if (GetBool(parameters["players"], false))
|
||||
|
|
@ -174,27 +258,32 @@ namespace TShockAPI
|
|||
rules.Add("PvPMode", TShock.Config.PvPMode);
|
||||
rules.Add("SpawnProtection", TShock.Config.SpawnProtection);
|
||||
rules.Add("SpawnProtectionRadius", TShock.Config.SpawnProtectionRadius);
|
||||
rules.Add("ServerSideInventory", TShock.Config.ServerSideInventory);
|
||||
|
||||
ret.Add("rules", rules);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private object ServerTokenTest(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object ServerTokenTest(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return RestResponse("Token is valid and was passed through correctly");
|
||||
return new RestObject()
|
||||
{
|
||||
{"response", "Token is valid and was passed through correctly."},
|
||||
{"associateduser", tokenData.Username}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region RestUserMethods
|
||||
|
||||
private object UserActiveListV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserActiveListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return new RestObject() { { "activeusers", string.Join("\t", TShock.Players.Where(p => null != p && null != p.UserAccountName && p.Active).Select(p => p.UserAccountName)) } };
|
||||
}
|
||||
|
||||
private object UserListV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return new RestObject() { { "users", TShock.Users.GetUsers().Select(p => new Dictionary<string,object>(){
|
||||
{"name", p.Name},
|
||||
|
|
@ -204,15 +293,15 @@ namespace TShockAPI
|
|||
}) } };
|
||||
}
|
||||
|
||||
private object UserCreateV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserCreateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var username = parameters["user"];
|
||||
if (string.IsNullOrWhiteSpace(username))
|
||||
return RestMissingParam("user");
|
||||
|
||||
var group = parameters["group"];
|
||||
if (string.IsNullOrWhiteSpace(group))
|
||||
return RestMissingParam("group");
|
||||
if (string.IsNullOrWhiteSpace(group))
|
||||
group = TShock.Config.DefaultRegistrationGroupName;
|
||||
|
||||
var password = parameters["password"];
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
|
|
@ -232,7 +321,7 @@ namespace TShockAPI
|
|||
return RestResponse("User was successfully created");
|
||||
}
|
||||
|
||||
private object UserUpdateV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserUpdateV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = UserFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -274,7 +363,7 @@ namespace TShockAPI
|
|||
return response;
|
||||
}
|
||||
|
||||
private object UserDestroyV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = UserFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -292,7 +381,7 @@ namespace TShockAPI
|
|||
return RestResponse("User deleted successfully");
|
||||
}
|
||||
|
||||
private object UserInfoV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object UserInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = UserFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -306,7 +395,7 @@ namespace TShockAPI
|
|||
|
||||
#region RestBanMethods
|
||||
|
||||
private object BanCreate(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object BanCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ip = parameters["ip"];
|
||||
var name = parameters["name"];
|
||||
|
|
@ -325,7 +414,7 @@ namespace TShockAPI
|
|||
return RestResponse("Ban created successfully");
|
||||
}
|
||||
|
||||
private object BanDestroyV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object BanDestroyV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = BanFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -357,7 +446,7 @@ namespace TShockAPI
|
|||
return RestResponse("Ban deleted successfully");
|
||||
}
|
||||
|
||||
private object BanInfoV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object BanInfoV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = BanFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -371,7 +460,7 @@ namespace TShockAPI
|
|||
};
|
||||
}
|
||||
|
||||
private object BanListV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object BanListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var banList = new ArrayList();
|
||||
foreach (var ban in TShock.Bans.GetBans())
|
||||
|
|
@ -393,7 +482,7 @@ namespace TShockAPI
|
|||
|
||||
#region RestWorldMethods
|
||||
|
||||
private object WorldChangeSaveSettings(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldChangeSaveSettings(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
bool autoSave;
|
||||
if (!bool.TryParse(verbs["bool"], out autoSave))
|
||||
|
|
@ -403,14 +492,14 @@ namespace TShockAPI
|
|||
return RestResponse("AutoSave has been set to " + autoSave);
|
||||
}
|
||||
|
||||
private object WorldSave(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldSave(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
SaveManager.Instance.SaveWorld();
|
||||
|
||||
return RestResponse("World saved");
|
||||
}
|
||||
|
||||
private object WorldButcher(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldButcher(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
bool killFriendly;
|
||||
if (!bool.TryParse(parameters["killfriendly"], out killFriendly))
|
||||
|
|
@ -432,7 +521,7 @@ namespace TShockAPI
|
|||
return RestResponse(killcount + " NPCs have been killed");
|
||||
}
|
||||
|
||||
private object WorldRead(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldRead(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return new RestObject()
|
||||
{
|
||||
|
|
@ -445,7 +534,7 @@ namespace TShockAPI
|
|||
};
|
||||
}
|
||||
|
||||
private object WorldMeteor(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldMeteor(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
if (null == WorldGen.genRand)
|
||||
WorldGen.genRand = new Random();
|
||||
|
|
@ -453,7 +542,7 @@ namespace TShockAPI
|
|||
return RestResponse("Meteor has been spawned");
|
||||
}
|
||||
|
||||
private object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object WorldBloodmoon(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
bool bloodmoon;
|
||||
if (!bool.TryParse(verbs["bool"], out bloodmoon))
|
||||
|
|
@ -467,23 +556,23 @@ namespace TShockAPI
|
|||
|
||||
#region RestPlayerMethods
|
||||
|
||||
private object PlayerUnMute(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerUnMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return PlayerSetMute(parameters, false);
|
||||
}
|
||||
|
||||
private object PlayerMute(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerMute(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
return PlayerSetMute(parameters, true);
|
||||
}
|
||||
|
||||
private object PlayerList(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var activeplayers = Main.player.Where(p => null != p && p.active).ToList();
|
||||
return new RestObject() { { "players", string.Join(", ", activeplayers.Select(p => p.name)) } };
|
||||
}
|
||||
|
||||
private object PlayerListV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerListV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var playerList = new ArrayList();
|
||||
foreach (TSPlayer tsPlayer in TShock.Players.Where(p => null != p))
|
||||
|
|
@ -495,7 +584,7 @@ namespace TShockAPI
|
|||
return new RestObject() { { "players", playerList } };
|
||||
}
|
||||
|
||||
private object PlayerReadV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerReadV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = PlayerFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -515,7 +604,7 @@ namespace TShockAPI
|
|||
};
|
||||
}
|
||||
|
||||
private object PlayerKickV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerKickV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = PlayerFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -526,7 +615,7 @@ namespace TShockAPI
|
|||
return RestResponse("Player " + player.Name + " was kicked");
|
||||
}
|
||||
|
||||
private object PlayerBanV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerBanV2(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = PlayerFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -539,7 +628,7 @@ namespace TShockAPI
|
|||
return RestResponse("Player " + player.Name + " was banned");
|
||||
}
|
||||
|
||||
private object PlayerKill(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object PlayerKill(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = PlayerFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -556,7 +645,7 @@ namespace TShockAPI
|
|||
|
||||
#region RestGroupMethods
|
||||
|
||||
private object GroupList(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object GroupList(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var groups = new ArrayList();
|
||||
foreach (Group group in TShock.Groups)
|
||||
|
|
@ -566,7 +655,7 @@ namespace TShockAPI
|
|||
return new RestObject() { { "groups", groups } };
|
||||
}
|
||||
|
||||
private object GroupInfo(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object GroupInfo(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = GroupFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -576,14 +665,14 @@ namespace TShockAPI
|
|||
return new RestObject() {
|
||||
{"name", group.Name},
|
||||
{"parent", group.ParentName},
|
||||
{"chatcolor", group.ChatColor},
|
||||
{"chatcolor", string.Format("{0},{1},{2}", group.R, group.G, group.B)},
|
||||
{"permissions", group.permissions},
|
||||
{"negatedpermissions", group.negatedpermissions},
|
||||
{"totalpermissions", group.TotalPermissions}
|
||||
};
|
||||
}
|
||||
|
||||
private object GroupDestroy(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object GroupDestroy(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = GroupFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -602,7 +691,7 @@ namespace TShockAPI
|
|||
return RestResponse("Group '" + group.Name + "' deleted successfully");
|
||||
}
|
||||
|
||||
private object GroupCreate(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object GroupCreate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var name = parameters["group"];
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
|
|
@ -619,7 +708,7 @@ namespace TShockAPI
|
|||
return RestResponse("Group '" + name + "' created successfully");
|
||||
}
|
||||
|
||||
private object GroupUpdate(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object GroupUpdate(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var ret = GroupFind(parameters);
|
||||
if (ret is RestObject)
|
||||
|
|
@ -627,7 +716,7 @@ namespace TShockAPI
|
|||
|
||||
Group group = (Group)ret;
|
||||
var parent = (null == parameters["parent"]) ? group.ParentName : parameters["parent"];
|
||||
var chatcolor = (null == parameters["chatcolor"]) ? group.ChatColor : parameters["chatcolor"];
|
||||
var chatcolor = (null == parameters["chatcolor"]) ? string.Format("{0}.{1}.{2}", group.R, group.G, group.B) : parameters["chatcolor"];
|
||||
var permissions = (null == parameters["permissions"]) ? group.Permissions : parameters["permissions"];
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
|
|
|||
92
TShockAPI/Rest/RestPermissions.cs
Normal file
92
TShockAPI/Rest/RestPermissions.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
public static class RestPermissions
|
||||
{
|
||||
[Description("User can create REST tokens.")]
|
||||
public static readonly string restapi;
|
||||
|
||||
[Description("User or REST user can destroy all REST tokens.")]
|
||||
public static readonly string restmanage;
|
||||
|
||||
|
||||
[Description("REST user can turn off / restart the server.")]
|
||||
public static readonly string restmaintenance;
|
||||
|
||||
[Description("REST user can reload configurations, save the world and set auto save settings.")]
|
||||
public static readonly string restcfg;
|
||||
|
||||
|
||||
[Description("REST user can list and get detailed information about users.")]
|
||||
public static readonly string restviewusers;
|
||||
|
||||
[Description("REST user can alter users.")]
|
||||
public static readonly string restmanageusers;
|
||||
|
||||
[Description("REST user can list and get detailed information about bans.")]
|
||||
public static readonly string restviewbans;
|
||||
|
||||
[Description("REST user can alter bans.")]
|
||||
public static readonly string restmanagebans;
|
||||
|
||||
[Description("REST user can list and get detailed information about groups.")]
|
||||
public static readonly string restviewgroups;
|
||||
|
||||
[Description("REST user can alter groups.")]
|
||||
public static readonly string restmanagegroups;
|
||||
|
||||
|
||||
[Description("REST user can get user information.")]
|
||||
public static readonly string restuserinfo;
|
||||
|
||||
[Description("REST user can kick players.")]
|
||||
public static readonly string restkick;
|
||||
|
||||
[Description("REST user can ban players.")]
|
||||
public static readonly string restban;
|
||||
|
||||
[Description("REST user can mute and unmute players.")]
|
||||
public static readonly string restmute;
|
||||
|
||||
[Description("REST user can kill players.")]
|
||||
public static readonly string restkill;
|
||||
|
||||
|
||||
[Description("REST user can drop meteors or change bloodmoon.")]
|
||||
public static readonly string restcauseevents;
|
||||
|
||||
[Description("REST user can butcher npcs.")]
|
||||
public static readonly string restbutcher;
|
||||
|
||||
|
||||
[Description("REST user can run raw TShock commands (the raw command permissions are also checked though).")]
|
||||
public static readonly string restrawcommand;
|
||||
|
||||
static RestPermissions()
|
||||
{
|
||||
foreach (var field in typeof (RestPermissions).GetFields())
|
||||
{
|
||||
field.SetValue(null, field.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,41 +15,76 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using HttpServer;
|
||||
using TShockAPI;
|
||||
using TShockAPI.DB;
|
||||
|
||||
namespace Rests
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="username">Username to verify</param>
|
||||
/// <param name="password">Password to verify</param>
|
||||
/// <returns>Returning a restobject with a null error means a successful verification.</returns>
|
||||
public delegate RestObject VerifyD(string username, string password);
|
||||
|
||||
public class SecureRest : Rest
|
||||
{
|
||||
public Dictionary<string, object> Tokens { get; protected set; }
|
||||
public event VerifyD Verify;
|
||||
public struct TokenData
|
||||
{
|
||||
public static readonly TokenData None = default(TokenData);
|
||||
|
||||
public string Username { get; set; }
|
||||
public string UserGroupName { get; set; }
|
||||
}
|
||||
|
||||
public Dictionary<string,TokenData> Tokens { get; protected set; }
|
||||
public Dictionary<string, TokenData> AppTokens { get; protected set; }
|
||||
|
||||
public SecureRest(IPAddress ip, int port)
|
||||
: base(ip, port)
|
||||
{
|
||||
Tokens = new Dictionary<string, object>();
|
||||
Register(new RestCommand("/token/create/{username}/{password}", NewToken) {RequiresToken = false});
|
||||
Register(new RestCommand("/v2/token/create/{password}", NewTokenV2) { RequiresToken = false });
|
||||
Register(new RestCommand("/token/destroy/{token}", DestroyToken) {RequiresToken = true});
|
||||
foreach (KeyValuePair<string, string> t in TShockAPI.TShock.RESTStartupTokens)
|
||||
Tokens = new Dictionary<string, TokenData>();
|
||||
AppTokens = new Dictionary<string, TokenData>();
|
||||
|
||||
Register(new RestCommand("/token/create/{username}/{password}", NewToken) { DoLog = false });
|
||||
Register(new RestCommand("/v2/token/create/{password}", NewTokenV2) { DoLog = false });
|
||||
Register(new SecureRestCommand("/token/destroy/{token}", DestroyToken));
|
||||
Register(new SecureRestCommand("/v3/token/destroy/all", DestroyAllTokens, RestPermissions.restmanage));
|
||||
|
||||
foreach (KeyValuePair<string, TokenData> t in TShockAPI.TShock.RESTStartupTokens)
|
||||
{
|
||||
Tokens.Add(t.Key, t.Value);
|
||||
AppTokens.Add(t.Key, t.Value);
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, TokenData> t in TShock.Config.ApplicationRestTokens)
|
||||
{
|
||||
AppTokens.Add(t.Key, t.Value);
|
||||
}
|
||||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestApiEnabled && !TShock.Config.RestUseNewPermissionModel)
|
||||
{
|
||||
string warningMessage = string.Concat(
|
||||
"You're using the old REST permission model which is highly vulnerable in matter of security. ",
|
||||
"The old model will be removed with the next maintenance release of TShock. In order to switch to the new model, ",
|
||||
"change the config setting \"RestUseNewPermissionModel\" to true."
|
||||
);
|
||||
Log.Warn(warningMessage);
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(warningMessage);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
}
|
||||
else if (TShock.Config.RestApiEnabled)
|
||||
{
|
||||
string warningMessage = string.Concat(
|
||||
"You're using the new more secure REST permission model which can lead to compatibility problems ",
|
||||
"with existing REST services. If compatibility problems occur, you can switch back to the unsecure permission ",
|
||||
"model by changing the config setting \"RestUseNewPermissionModel\" to false, which is not recommended."
|
||||
);
|
||||
Log.ConsoleInfo(warningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private object DestroyToken(RestVerbs verbs, IParameterCollection parameters)
|
||||
private object DestroyToken(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
var token = verbs["token"];
|
||||
try
|
||||
|
|
@ -58,11 +93,19 @@ namespace Rests
|
|||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return new Dictionary<string, string>
|
||||
{{"status", "400"}, {"error", "The specified token queued for destruction failed to be deleted."}};
|
||||
return new RestObject("400")
|
||||
{ Error = "The specified token queued for destruction failed to be deleted." };
|
||||
}
|
||||
return new Dictionary<string, string>
|
||||
{{"status", "200"}, {"response", "Requested token was successfully destroyed."}};
|
||||
return new RestObject()
|
||||
{ Response = "Requested token was successfully destroyed." };
|
||||
}
|
||||
|
||||
private object DestroyAllTokens(RestVerbs verbs, IParameterCollection parameters, SecureRest.TokenData tokenData)
|
||||
{
|
||||
Tokens.Clear();
|
||||
|
||||
return new RestObject()
|
||||
{ Response = "All tokens were successfully destroyed." };
|
||||
}
|
||||
|
||||
private object NewTokenV2(RestVerbs verbs, IParameterCollection parameters)
|
||||
|
|
@ -70,29 +113,7 @@ namespace Rests
|
|||
var user = parameters["username"];
|
||||
var pass = verbs["password"];
|
||||
|
||||
RestObject obj = null;
|
||||
if (Verify != null)
|
||||
obj = Verify(user, pass);
|
||||
|
||||
if (obj == null)
|
||||
obj = new RestObject("401") { Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." };
|
||||
|
||||
if (obj.Error != null)
|
||||
return obj;
|
||||
|
||||
string hash;
|
||||
var rand = new Random();
|
||||
var randbytes = new byte[32];
|
||||
do
|
||||
{
|
||||
rand.NextBytes(randbytes);
|
||||
hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
} while (Tokens.ContainsKey(hash));
|
||||
|
||||
Tokens.Add(hash, user);
|
||||
|
||||
obj["token"] = hash;
|
||||
return obj;
|
||||
return this.NewTokenInternal(user, pass);
|
||||
}
|
||||
|
||||
private object NewToken(RestVerbs verbs, IParameterCollection parameters)
|
||||
|
|
@ -100,55 +121,84 @@ namespace Rests
|
|||
var user = verbs["username"];
|
||||
var pass = verbs["password"];
|
||||
|
||||
RestObject obj = null;
|
||||
if (Verify != null)
|
||||
obj = Verify(user, pass);
|
||||
RestObject response = this.NewTokenInternal(user, pass);
|
||||
response["deprecated"] = "This endpoint is depracted and will be removed in the future.";
|
||||
return response;
|
||||
}
|
||||
|
||||
if (obj == null)
|
||||
obj = new RestObject("401")
|
||||
{Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."};
|
||||
private RestObject NewTokenInternal(string username, string password)
|
||||
{
|
||||
User userAccount = TShock.Users.GetUserByName(username);
|
||||
if (userAccount == null || !string.IsNullOrWhiteSpace(userAccount.Address))
|
||||
return new RestObject("401")
|
||||
{ Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." };
|
||||
|
||||
if (!TShock.Utils.HashPassword(password).Equals(userAccount.Password, StringComparison.InvariantCultureIgnoreCase))
|
||||
return new RestObject("401")
|
||||
{ Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair." };
|
||||
|
||||
if (obj.Error != null)
|
||||
return obj;
|
||||
|
||||
string hash;
|
||||
Group userGroup = TShock.Utils.GetGroup(userAccount.Group);
|
||||
if (!userGroup.HasPermission(RestPermissions.restapi) && userAccount.Group != "superadmin")
|
||||
return new RestObject("403")
|
||||
{ Error = "Although your account was successfully found and identified, your account lacks the permission required to use the API. (restapi)" };
|
||||
|
||||
string tokenHash;
|
||||
var rand = new Random();
|
||||
var randbytes = new byte[32];
|
||||
do
|
||||
{
|
||||
rand.NextBytes(randbytes);
|
||||
hash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
} while (Tokens.ContainsKey(hash));
|
||||
tokenHash = randbytes.Aggregate("", (s, b) => s + b.ToString("X2"));
|
||||
} while (Tokens.ContainsKey(tokenHash));
|
||||
|
||||
Tokens.Add(hash, user);
|
||||
Tokens.Add(tokenHash, new TokenData { Username = userAccount.Name, UserGroupName = userGroup.Name });
|
||||
|
||||
obj["token"] = hash;
|
||||
obj["deprecated"] = "This method will be removed from TShock in 3.6.";
|
||||
return obj;
|
||||
RestObject response = new RestObject() { Response = "Successful login" };
|
||||
response["token"] = tokenHash;
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
protected override object ExecuteCommand(RestCommand cmd, RestVerbs verbs, IParameterCollection parms)
|
||||
{
|
||||
if (cmd.RequiresToken)
|
||||
{
|
||||
var strtoken = parms["token"];
|
||||
if (strtoken == null)
|
||||
return new Dictionary<string, string>
|
||||
{{"status", "401"}, {"error", "Not authorized. The specified API endpoint requires a token."}};
|
||||
if (!cmd.RequiresToken)
|
||||
return base.ExecuteCommand(cmd, verbs, parms);
|
||||
|
||||
var token = parms["token"];
|
||||
if (token == null)
|
||||
return new RestObject("401")
|
||||
{ Error = "Not authorized. The specified API endpoint requires a token." };
|
||||
|
||||
object token;
|
||||
if (!Tokens.TryGetValue(strtoken, out token))
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
{"status", "403"},
|
||||
{
|
||||
"error",
|
||||
"Not authorized. The specified API endpoint requires a token, but the provided token was not valid."
|
||||
}
|
||||
};
|
||||
SecureRestCommand secureCmd = (SecureRestCommand)cmd;
|
||||
TokenData tokenData;
|
||||
if (!Tokens.TryGetValue(token, out tokenData) && !AppTokens.TryGetValue(token, out tokenData))
|
||||
return new RestObject("403")
|
||||
{ Error = "Not authorized. The specified API endpoint requires a token, but the provided token was not valid." };
|
||||
|
||||
// TODO: Get rid of this when the old REST permission model is removed.
|
||||
if (TShock.Config.RestUseNewPermissionModel) {
|
||||
Group userGroup = TShock.Groups.GetGroupByName(tokenData.UserGroupName);
|
||||
if (userGroup == null)
|
||||
{
|
||||
Tokens.Remove(token);
|
||||
|
||||
return new RestObject("403")
|
||||
{ Error = "Not authorized. The provided token became invalid due to group changes, please create a new token." };
|
||||
}
|
||||
|
||||
if (secureCmd.Permissions.Length > 0 && secureCmd.Permissions.All(perm => !userGroup.HasPermission(perm)))
|
||||
{
|
||||
return new RestObject("403")
|
||||
{ Error = string.Format("Not authorized. User \"{0}\" has no access to use the specified API endpoint.", tokenData.Username) };
|
||||
}
|
||||
}
|
||||
return base.ExecuteCommand(cmd, verbs, parms);
|
||||
|
||||
object result = secureCmd.Execute(verbs, parms, tokenData);
|
||||
if (cmd.DoLog)
|
||||
TShock.Utils.SendLogs(string.Format(
|
||||
"\"{0}\" requested REST endpoint: {1}", tokenData.Username, this.BuildRequestUri(cmd, verbs, parms, false)),
|
||||
Color.PaleVioletRed);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,24 @@
|
|||
using System;
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
|
||||
This program 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, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using Terraria;
|
||||
|
||||
namespace TShockAPI
|
||||
{
|
||||
public class StatTracker
|
||||
{
|
||||
private Utils Utils = TShock.Utils;
|
||||
public DateTime lastcheck = DateTime.MinValue;
|
||||
private readonly int checkinFrequency = 5;
|
||||
|
||||
public void CheckIn()
|
||||
{
|
||||
if ((DateTime.Now - lastcheck).TotalMinutes >= checkinFrequency)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(CallHome);
|
||||
lastcheck = DateTime.Now;
|
||||
}
|
||||
}
|
||||
|
||||
private void CallHome(object state)
|
||||
{
|
||||
string fp;
|
||||
string lolpath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/.tshock/";
|
||||
if (!Directory.Exists(lolpath))
|
||||
{
|
||||
Directory.CreateDirectory(lolpath);
|
||||
}
|
||||
if (!File.Exists(Path.Combine(lolpath, Netplay.serverPort + ".fingerprint")))
|
||||
{
|
||||
fp = "";
|
||||
int random = Utils.Random.Next(500000, 1000000);
|
||||
fp += random;
|
||||
|
||||
fp = Utils.HashPassword(Netplay.serverIP + fp + Netplay.serverPort + Netplay.serverListenIP);
|
||||
TextWriter tw = new StreamWriter(Path.Combine(lolpath, Netplay.serverPort + ".fingerprint"));
|
||||
tw.Write(fp);
|
||||
tw.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
fp = "";
|
||||
TextReader tr = new StreamReader(Path.Combine(lolpath, Netplay.serverPort + ".fingerprint"));
|
||||
fp = tr.ReadToEnd();
|
||||
tr.Close();
|
||||
}
|
||||
|
||||
using (var client = new WebClient())
|
||||
{
|
||||
client.Headers.Add("user-agent",
|
||||
"TShock (" + TShock.VersionNum + ")");
|
||||
try
|
||||
{
|
||||
string response;
|
||||
if (TShock.Config.DisablePlayerCountReporting)
|
||||
{
|
||||
response =
|
||||
client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" +
|
||||
Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort +
|
||||
"&plcount=0");
|
||||
}
|
||||
else
|
||||
{
|
||||
response =
|
||||
client.DownloadString("http://tshock.co/tickto.php?do=log&fp=" + fp + "&ver=" + TShock.VersionNum + "&os=" +
|
||||
Environment.OSVersion + "&mono=" + Main.runningMono + "&port=" + Netplay.serverPort +
|
||||
"&plcount=" + TShock.Utils.ActivePlayers());
|
||||
}
|
||||
if (!TShock.Config.HideStatTrackerDebugMessages)
|
||||
Log.ConsoleInfo("Stat Tracker: " + response);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
|
@ -27,61 +28,258 @@ namespace TShockAPI
|
|||
{
|
||||
public class TSPlayer
|
||||
{
|
||||
/// <summary>
|
||||
/// This represents the server as a player.
|
||||
/// </summary>
|
||||
public static readonly TSServerPlayer Server = new TSServerPlayer();
|
||||
|
||||
/// <summary>
|
||||
/// This player represents all the players.
|
||||
/// </summary>
|
||||
public static readonly TSPlayer All = new TSPlayer("All");
|
||||
|
||||
/// <summary>
|
||||
/// The amount of tiles that the player has killed in the last second.
|
||||
/// </summary>
|
||||
public int TileKillThreshold { get; set; }
|
||||
public int TilePlaceThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of tiles the player has placed in the last second.
|
||||
/// </summary>
|
||||
public int TilePlaceThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The amount of liquid( in tiles ) that the player has placed in the last second.
|
||||
/// </summary>
|
||||
public int TileLiquidThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The number of projectiles created by the player in the last second.
|
||||
/// </summary>
|
||||
public int ProjectileThreshold { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A queue of tiles destroyed by the player for reverting.
|
||||
/// </summary>
|
||||
public Dictionary<Vector2, TileData> TilesDestroyed { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// A queue of tiles placed by the player for reverting.
|
||||
/// </summary>
|
||||
public Dictionary<Vector2, TileData> TilesCreated { get; protected set; }
|
||||
|
||||
public int FirstMaxHP { get; set; }
|
||||
|
||||
public int FirstMaxMP { get; set; }
|
||||
public Group Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's group.
|
||||
/// </summary>
|
||||
public Group Group
|
||||
{
|
||||
get
|
||||
{
|
||||
if (tempGroup != null)
|
||||
return tempGroup;
|
||||
return group;
|
||||
}
|
||||
set { group = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The player's temporary group. This overrides the user's actual group.
|
||||
/// </summary>
|
||||
public Group tempGroup = null;
|
||||
|
||||
private Group group = null;
|
||||
|
||||
public bool ReceivedInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The players index in the player array( Main.players[] ).
|
||||
/// </summary>
|
||||
public int Index { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last time the player changed their team or pvp status.
|
||||
/// </summary>
|
||||
public DateTime LastPvpChange;
|
||||
|
||||
/// <summary>
|
||||
/// Temp points for use in regions and other plugins.
|
||||
/// </summary>
|
||||
public Point[] TempPoints = new Point[2];
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is waiting to place/break a tile to set as a temp point.
|
||||
/// </summary>
|
||||
public int AwaitingTempPoint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A list of command callbacks indexed by the command they need to do.
|
||||
/// </summary>
|
||||
public Dictionary<string, Action<object>> AwaitingResponse;
|
||||
|
||||
public bool AwaitingName { get; set; }
|
||||
|
||||
public string[] AwaitingNameParameters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The last time a player broke a grief check.
|
||||
/// </summary>
|
||||
public DateTime LastThreat { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Not used, can be removed.
|
||||
/// </summary>
|
||||
public DateTime LastTileChangeNotify { get; set; }
|
||||
|
||||
public bool InitSpawn;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player should see logs.
|
||||
/// </summary>
|
||||
public bool DisplayLogs = true;
|
||||
|
||||
public Vector2 oldSpawn = Vector2.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The last player that the player whispered with( to or from ).
|
||||
/// </summary>
|
||||
public TSPlayer LastWhisper;
|
||||
|
||||
/// <summary>
|
||||
/// The number of unsuccessful login attempts.
|
||||
/// </summary>
|
||||
public int LoginAttempts { get; set; }
|
||||
|
||||
public Vector2 TeleportCoords = new Vector2(-1, -1);
|
||||
|
||||
public Vector2 LastNetPosition = Vector2.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The player's login name.
|
||||
/// </summary>
|
||||
public string UserAccountName { get; set; }
|
||||
public bool HasBeenSpammedWithBuildMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player performed a valid login attempt (i.e. entered valid user name and password) but is still blocked
|
||||
/// from logging in because of SSI.
|
||||
/// </summary>
|
||||
public bool LoginFailsBySsi { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is logged in or not.
|
||||
/// </summary>
|
||||
public bool IsLoggedIn;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has sent their whole inventory to the server while connecting.
|
||||
/// </summary>
|
||||
public bool HasSentInventory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The player's user id( from the db ).
|
||||
/// </summary>
|
||||
public int UserID = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has been nagged about logging in.
|
||||
/// </summary>
|
||||
public bool HasBeenNaggedAboutLoggingIn;
|
||||
public bool TPAllow = true;
|
||||
|
||||
public bool TPAllow = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is muted or not.
|
||||
/// </summary>
|
||||
public bool mute;
|
||||
|
||||
public bool TpLock;
|
||||
|
||||
private Player FakePlayer;
|
||||
|
||||
public bool RequestedSection;
|
||||
|
||||
/// <summary>
|
||||
/// The last time the player died.
|
||||
/// </summary>
|
||||
public DateTime LastDeath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is dead or not.
|
||||
/// </summary>
|
||||
public bool Dead;
|
||||
|
||||
public string Country = "??";
|
||||
|
||||
/// <summary>
|
||||
/// The players difficulty( normal[softcore], mediumcore, hardcore ).
|
||||
/// </summary>
|
||||
public int Difficulty;
|
||||
|
||||
private string CacheIP;
|
||||
|
||||
public string IgnoreActionsForInventory = "none";
|
||||
|
||||
public string IgnoreActionsForCheating = "none";
|
||||
|
||||
public string IgnoreActionsForDisabledArmor = "none";
|
||||
|
||||
public bool IgnoreActionsForClearingTrashCan;
|
||||
|
||||
/// <summary>
|
||||
/// The player's server side inventory data.
|
||||
/// </summary>
|
||||
public PlayerData PlayerData;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player needs to specify a password upon connection( either server or user account ).
|
||||
/// </summary>
|
||||
public bool RequiresPassword;
|
||||
|
||||
public bool SilentKickInProgress;
|
||||
|
||||
public bool SilentJoinInProgress;
|
||||
|
||||
/// <summary>
|
||||
/// A list of points where ice tiles have been placed.
|
||||
/// </summary>
|
||||
public List<Point> IceTiles;
|
||||
public long RPm = 1;
|
||||
public long WPm = 1;
|
||||
public long SPm = 1;
|
||||
public long BPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Unused, can be removed.
|
||||
/// </summary>
|
||||
public long RPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// World protection message cool down.
|
||||
/// </summary>
|
||||
public long WPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Spawn protection message cool down.
|
||||
/// </summary>
|
||||
public long SPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Permission to build message cool down.
|
||||
/// </summary>
|
||||
public long BPm = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The time in ms when the player has logged in.
|
||||
/// </summary>
|
||||
public long LoginMS;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player has been harrassed about logging in due to server side inventory or forced login.
|
||||
/// </summary>
|
||||
public bool LoginHarassed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Whether the player is a real, human, player on the server.
|
||||
/// </summary>
|
||||
public bool RealPlayer
|
||||
{
|
||||
get { return Index >= 0 && Index < Main.maxNetPlayers && Main.player[Index] != null; }
|
||||
|
|
@ -212,6 +410,7 @@ namespace TShockAPI
|
|||
Index = index;
|
||||
Group = new Group(TShock.Config.DefaultGuestGroupName);
|
||||
IceTiles = new List<Point>();
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
}
|
||||
|
||||
protected TSPlayer(String playerName)
|
||||
|
|
@ -221,6 +420,7 @@ namespace TShockAPI
|
|||
Index = -1;
|
||||
FakePlayer = new Player {name = playerName, whoAmi = -1};
|
||||
Group = new Group(TShock.Config.DefaultGuestGroupName);
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
}
|
||||
|
||||
public virtual void Disconnect(string reason)
|
||||
|
|
@ -384,7 +584,8 @@ namespace TShockAPI
|
|||
|
||||
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))
|
||||
return false;
|
||||
|
||||
GiveItem(type,name,width,height,stack,prefix);
|
||||
|
|
@ -407,9 +608,14 @@ namespace TShockAPI
|
|||
NetMessage.SendData((int) PacketTypes.ItemOwner, -1, -1, "", itemid, 0f, 0f, 0f);
|
||||
}
|
||||
|
||||
public virtual void SendInformationalMessage(string msg)
|
||||
public virtual void SendInfoMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Indigo);
|
||||
SendMessage(msg, Color.Yellow);
|
||||
}
|
||||
|
||||
public void SendInfoMessage(string format, params object[] args)
|
||||
{
|
||||
SendInfoMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendSuccessMessage(string msg)
|
||||
|
|
@ -417,9 +623,19 @@ namespace TShockAPI
|
|||
SendMessage(msg, Color.Green);
|
||||
}
|
||||
|
||||
public void SendSuccessMessage(string format, params object[] args)
|
||||
{
|
||||
SendSuccessMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendWarningMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Yellow);
|
||||
SendMessage(msg, Color.OrangeRed);
|
||||
}
|
||||
|
||||
public void SendWarningMessage(string format, params object[] args)
|
||||
{
|
||||
SendWarningMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
public virtual void SendErrorMessage(string msg)
|
||||
|
|
@ -427,6 +643,12 @@ namespace TShockAPI
|
|||
SendMessage(msg, Color.Red);
|
||||
}
|
||||
|
||||
public void SendErrorMessage(string format, params object[] args)
|
||||
{
|
||||
SendErrorMessage(string.Format(format, args));
|
||||
}
|
||||
|
||||
[Obsolete("Use SendErrorMessage, SendInfoMessage, or SendWarningMessage, or a custom color instead.")]
|
||||
public virtual void SendMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, 0, 255, 0);
|
||||
|
|
@ -466,13 +688,13 @@ namespace TShockAPI
|
|||
SetBuff(32, 330, true); //Slow
|
||||
SetBuff(23, 330, true); //Cursed
|
||||
if (!string.IsNullOrEmpty(reason))
|
||||
Log.ConsoleInfo(string.Format("Player {0} has been disabled for {1}", Name, reason));
|
||||
Log.ConsoleInfo(string.Format("Player {0} has been disabled for {1}.", Name, reason));
|
||||
|
||||
var trace = new StackTrace();
|
||||
StackFrame frame = null;
|
||||
frame = trace.GetFrame(1);
|
||||
if (frame != null && frame.GetMethod().DeclaringType != null)
|
||||
Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable()");
|
||||
Log.Debug(frame.GetMethod().DeclaringType.Name + " called Disable().");
|
||||
}
|
||||
|
||||
public virtual void Whoopie(object time)
|
||||
|
|
@ -521,15 +743,31 @@ namespace TShockAPI
|
|||
|
||||
return TShock.SendBytes(Netplay.serverSock[Index], data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a command callback to a specified command string.
|
||||
/// </summary>
|
||||
/// <param name="name">The string representing the command i.e "yes" == /yes</param>
|
||||
/// <param name="callback">The method that will be executed on confirmation ie user accepts</param>
|
||||
public void AddResponse( string name, Action<object> callback)
|
||||
{
|
||||
if( AwaitingResponse.ContainsKey(name))
|
||||
{
|
||||
AwaitingResponse.Remove(name);
|
||||
}
|
||||
|
||||
AwaitingResponse.Add(name, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public class TSRestPlayer : TSServerPlayer
|
||||
public class TSRestPlayer : TSPlayer
|
||||
{
|
||||
internal List<string> CommandReturn = new List<string>();
|
||||
internal List<string> CommandOutput = new List<string>();
|
||||
|
||||
public TSRestPlayer()
|
||||
public TSRestPlayer(string playerName, Group playerGroup): base(playerName)
|
||||
{
|
||||
Group = new SuperAdminGroup();
|
||||
Group = playerGroup;
|
||||
AwaitingResponse = new Dictionary<string, Action<object>>();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg)
|
||||
|
|
@ -544,12 +782,32 @@ namespace TShockAPI
|
|||
|
||||
public override void SendMessage(string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
CommandReturn.Add(msg);
|
||||
this.CommandOutput.Add(msg);
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Yellow);
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Green);
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.OrangeRed);
|
||||
}
|
||||
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, Color.Red);
|
||||
}
|
||||
|
||||
public List<string> GetCommandOutput()
|
||||
{
|
||||
return CommandReturn;
|
||||
return this.CommandOutput;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -561,6 +819,34 @@ namespace TShockAPI
|
|||
Group = new SuperAdminGroup();
|
||||
}
|
||||
|
||||
public override void SendErrorMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendInfoMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendSuccessMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendWarningMessage(string msg)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.DarkRed;
|
||||
Console.WriteLine(msg);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public override void SendMessage(string msg)
|
||||
{
|
||||
SendMessage(msg, 0, 255, 0);
|
||||
|
|
@ -614,6 +900,10 @@ namespace TShockAPI
|
|||
|
||||
public void StrikeNPC(int npcid, int damage, float knockBack, int hitDirection)
|
||||
{
|
||||
// Main.rand is thread static.
|
||||
if (Main.rand == null)
|
||||
Main.rand = new Random();
|
||||
|
||||
Main.npc[npcid].StrikeNPC(damage, knockBack, hitDirection);
|
||||
NetMessage.SendData((int) PacketTypes.NpcStrike, -1, -1, "", npcid, damage, knockBack, hitDirection);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
|
@ -25,7 +26,6 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Hooks;
|
||||
using MaxMind;
|
||||
using Mono.Data.Sqlite;
|
||||
|
|
@ -37,26 +37,28 @@ using TShockAPI.Net;
|
|||
|
||||
namespace TShockAPI
|
||||
{
|
||||
[APIVersion(1, 12)]
|
||||
[APIVersion(1, 13)]
|
||||
public class TShock : TerrariaPlugin
|
||||
{
|
||||
private const string LogFormatDefault = "yyyyMMddHHmmss";
|
||||
private static string LogFormat = LogFormatDefault;
|
||||
private static bool LogClear = false;
|
||||
public static readonly Version VersionNum = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
public static readonly string VersionCodename = "4.x & 50,000th download milestone";
|
||||
public static readonly string VersionCodename = "Welcome to the future.";
|
||||
|
||||
public static string SavePath = "tshock";
|
||||
private const string LogFormatDefault = "yyyy-MM-dd_HH-mm-ss";
|
||||
private static string LogFormat = LogFormatDefault;
|
||||
private const string LogPathDefault = "tshock";
|
||||
private static string LogPath = LogPathDefault;
|
||||
private static bool LogClear = false;
|
||||
|
||||
public static TSPlayer[] Players = new TSPlayer[Main.maxPlayers];
|
||||
public static BanManager Bans;
|
||||
public static WarpManager Warps;
|
||||
public static RegionManager Regions;
|
||||
public static RegionManager Regions;
|
||||
public static BackupManager Backups;
|
||||
public static GroupManager Groups;
|
||||
public static UserManager Users;
|
||||
public static ItemManager Itembans;
|
||||
public static RemeberedPosManager RememberedPos;
|
||||
public static RememberedPosManager RememberedPos;
|
||||
public static InventoryManager InventoryDB;
|
||||
public static ConfigFile Config { get; set; }
|
||||
public static IDbConnection DB;
|
||||
|
|
@ -66,11 +68,10 @@ namespace TShockAPI
|
|||
public static SecureRest RestApi;
|
||||
public static RestManager RestManager;
|
||||
public static Utils Utils = Utils.Instance;
|
||||
public static StatTracker StatTracker = new StatTracker();
|
||||
/// <summary>
|
||||
/// Used for implementing REST Tokens prior to the REST system starting up.
|
||||
/// </summary>
|
||||
public static Dictionary<string, string> RESTStartupTokens = new Dictionary<string, string>();
|
||||
public static Dictionary<string, SecureRest.TokenData> RESTStartupTokens = new Dictionary<string, SecureRest.TokenData>();
|
||||
|
||||
/// <summary>
|
||||
/// Called after TShock is initialized. Useful for plugins that needs hooks before tshock but also depend on tshock being loaded.
|
||||
|
|
@ -97,6 +98,10 @@ namespace TShockAPI
|
|||
get { return "The administration modification of the future."; }
|
||||
}
|
||||
|
||||
public override string UpdateURL
|
||||
{
|
||||
get { return ""; }
|
||||
}
|
||||
public TShock(Main game)
|
||||
: base(game)
|
||||
{
|
||||
|
|
@ -108,35 +113,57 @@ namespace TShockAPI
|
|||
[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
|
||||
public override void Initialize()
|
||||
{
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (!Directory.Exists(SavePath))
|
||||
Directory.CreateDirectory(SavePath);
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
string logFilename;
|
||||
try
|
||||
{
|
||||
logFilename = Path.Combine(SavePath, now.ToString(LogFormat)+".log");
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
// Problem with the log format use the default
|
||||
logFilename = Path.Combine(SavePath, now.ToString(LogFormatDefault) + ".log");
|
||||
}
|
||||
HandleCommandLine(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Version.Major >= 4)
|
||||
getTShockAscii();
|
||||
|
||||
if (!Directory.Exists(SavePath))
|
||||
Directory.CreateDirectory(SavePath);
|
||||
|
||||
ConfigFile.ConfigRead += OnConfigRead;
|
||||
FileTools.SetupConfig();
|
||||
|
||||
DateTime now = DateTime.Now;
|
||||
string logFilename;
|
||||
string logPathSetupWarning = null;
|
||||
// Log path was not already set by the command line parameter?
|
||||
if (LogPath == LogPathDefault)
|
||||
LogPath = Config.LogPath;
|
||||
try
|
||||
{
|
||||
logFilename = Path.Combine(LogPath, now.ToString(LogFormat)+".log");
|
||||
if (!Directory.Exists(LogPath))
|
||||
Directory.CreateDirectory(LogPath);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
logPathSetupWarning = "Could not apply the given log path / log format, defaults will be used. Exception details:\n" + ex;
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(logPathSetupWarning);
|
||||
Console.ForegroundColor = ConsoleColor.Gray;
|
||||
// Problem with the log path or format use the default
|
||||
logFilename = Path.Combine(LogPathDefault, now.ToString(LogFormatDefault) + ".log");
|
||||
}
|
||||
#if DEBUG
|
||||
Log.Initialize(logFilename, LogLevel.All, false);
|
||||
Log.Initialize(logFilename, LogLevel.All, false);
|
||||
#else
|
||||
Log.Initialize(logFilename, LogLevel.All & ~LogLevel.Debug, LogClear);
|
||||
Log.Initialize(logFilename, LogLevel.All & ~LogLevel.Debug, LogClear);
|
||||
#endif
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
||||
if (Version.Major >= 4)
|
||||
{
|
||||
getTShockAscii();
|
||||
}
|
||||
if (logPathSetupWarning != null)
|
||||
Log.Warn(logPathSetupWarning);
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
// Will be handled by the server api and written to its crashlog.txt.
|
||||
throw new Exception("Fatal TShock initialization exception. See inner exception for details.", ex);
|
||||
}
|
||||
|
||||
// Further exceptions are written to TShock's log from now on.
|
||||
try
|
||||
{
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
|
|
@ -147,9 +174,6 @@ namespace TShockAPI
|
|||
}
|
||||
File.WriteAllText(Path.Combine(SavePath, "tshock.pid"), Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
ConfigFile.ConfigRead += OnConfigRead;
|
||||
FileTools.SetupConfig();
|
||||
|
||||
HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
|
||||
if (Config.StorageType.ToLower() == "sqlite")
|
||||
|
|
@ -188,14 +212,13 @@ namespace TShockAPI
|
|||
Backups.Interval = Config.BackupInterval;
|
||||
Bans = new BanManager(DB);
|
||||
Warps = new WarpManager(DB);
|
||||
Regions = new RegionManager(DB);
|
||||
Users = new UserManager(DB);
|
||||
Groups = new GroupManager(DB);
|
||||
Regions = new RegionManager(DB);
|
||||
Itembans = new ItemManager(DB);
|
||||
RememberedPos = new RemeberedPosManager(DB);
|
||||
RememberedPos = new RememberedPosManager(DB);
|
||||
InventoryDB = new InventoryManager(DB);
|
||||
RestApi = new SecureRest(Netplay.serverListenIP, Config.RestApiPort);
|
||||
RestApi.Verify += RestApi_Verify;
|
||||
RestApi.Port = Config.RestApiPort;
|
||||
RestManager = new RestManager(RestApi);
|
||||
RestManager.RegisterRestfulCommands();
|
||||
|
|
@ -223,6 +246,8 @@ namespace TShockAPI
|
|||
ProjectileHooks.SetDefaults += OnProjectileSetDefaults;
|
||||
WorldHooks.StartHardMode += OnStartHardMode;
|
||||
WorldHooks.SaveWorld += SaveManager.Instance.OnSaveWorld;
|
||||
WorldHooks.ChristmasCheck += OnXmasCheck;
|
||||
NetHooks.NameCollision += NetHooks_NameCollision;
|
||||
|
||||
GetDataHandlers.InitGetDataHandler();
|
||||
Commands.InitCommands();
|
||||
|
|
@ -267,33 +292,6 @@ namespace TShockAPI
|
|||
// ReSharper restore LocalizableElement
|
||||
}
|
||||
|
||||
private RestObject RestApi_Verify(string username, string password)
|
||||
{
|
||||
var userAccount = Users.GetUserByName(username);
|
||||
if (userAccount == null)
|
||||
{
|
||||
return new RestObject("401")
|
||||
{Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."};
|
||||
}
|
||||
|
||||
if (Utils.HashPassword(password).ToUpper() != userAccount.Password.ToUpper())
|
||||
{
|
||||
return new RestObject("401")
|
||||
{Error = "Invalid username/password combination provided. Please re-submit your query with a correct pair."};
|
||||
}
|
||||
|
||||
if (!Utils.GetGroup(userAccount.Group).HasPermission(Permissions.restapi) && userAccount.Group != "superadmin")
|
||||
{
|
||||
return new RestObject("403")
|
||||
{
|
||||
Error =
|
||||
"Although your account was successfully found and identified, your account lacks the permission required to use the API. (api)"
|
||||
};
|
||||
}
|
||||
|
||||
return new RestObject("200") {Response = "Successful login"}; //Maybe return some user info too?
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
|
|
@ -322,6 +320,8 @@ namespace TShockAPI
|
|||
ProjectileHooks.SetDefaults -= OnProjectileSetDefaults;
|
||||
WorldHooks.StartHardMode -= OnStartHardMode;
|
||||
WorldHooks.SaveWorld -= SaveManager.Instance.OnSaveWorld;
|
||||
WorldHooks.ChristmasCheck -= OnXmasCheck;
|
||||
NetHooks.NameCollision -= NetHooks_NameCollision;
|
||||
|
||||
if (File.Exists(Path.Combine(SavePath, "tshock.pid")))
|
||||
{
|
||||
|
|
@ -334,6 +334,48 @@ namespace TShockAPI
|
|||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
void NetHooks_NameCollision(int who, string name, HandledEventArgs e)
|
||||
{
|
||||
string ip = TShock.Utils.GetRealIP(Netplay.serverSock[who].tcpClient.Client.RemoteEndPoint.ToString());
|
||||
foreach (TSPlayer ply in TShock.Players)
|
||||
{
|
||||
if (ply == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (ply.Name == name && ply.Index != who)
|
||||
{
|
||||
if (ply.IP == ip)
|
||||
{
|
||||
if (ply.State < 2)
|
||||
{
|
||||
Utils.ForceKick(ply, "Name collision and this client has no world data.", true, false);
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Handled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
e.Handled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
void OnXmasCheck(ChristmasCheckEventArgs args)
|
||||
{
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if(Config.ForceXmas)
|
||||
{
|
||||
args.Xmas = true;
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Handles exceptions that we didn't catch or that Red fucked up
|
||||
/// </summary>
|
||||
|
|
@ -396,9 +438,13 @@ namespace TShockAPI
|
|||
}
|
||||
break;
|
||||
|
||||
case "-dump":
|
||||
ConfigFile.DumpDescriptions();
|
||||
Permissions.DumpDescriptions();
|
||||
case "-logpath":
|
||||
path = parms[++i];
|
||||
if (path.IndexOfAny(Path.GetInvalidPathChars()) == -1)
|
||||
{
|
||||
LogPath = path;
|
||||
Log.ConsoleInfo("Log path has been set to " + path);
|
||||
}
|
||||
break;
|
||||
|
||||
case "-logformat":
|
||||
|
|
@ -408,6 +454,11 @@ namespace TShockAPI
|
|||
case "-logclear":
|
||||
bool.TryParse(parms[++i], out LogClear);
|
||||
break;
|
||||
|
||||
case "-dump":
|
||||
ConfigFile.DumpDescriptions();
|
||||
Permissions.DumpDescriptions();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -427,7 +478,7 @@ namespace TShockAPI
|
|||
break;
|
||||
case "-rest-token":
|
||||
string token = Convert.ToString(parms[++i]);
|
||||
RESTStartupTokens.Add(token, "null");
|
||||
RESTStartupTokens.Add(token, new SecureRest.TokenData { Username = "null", UserGroupName = "superadmin" });
|
||||
Console.WriteLine("Startup parameter overrode REST token.");
|
||||
break;
|
||||
case "-rest-enabled":
|
||||
|
|
@ -488,14 +539,20 @@ namespace TShockAPI
|
|||
{
|
||||
AuthToken = 0;
|
||||
}
|
||||
Regions.ReloadAllRegions();
|
||||
|
||||
StatTracker.CheckIn();
|
||||
Regions.ReloadAllRegions();
|
||||
|
||||
Lighting.lightMode = 2;
|
||||
FixChestStacks();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void FixChestStacks()
|
||||
{
|
||||
if (Config.IgnoreChestStacksOnLoad)
|
||||
return;
|
||||
|
||||
foreach (Chest chest in Main.chest)
|
||||
{
|
||||
if (chest != null)
|
||||
|
|
@ -515,7 +572,6 @@ namespace TShockAPI
|
|||
private void OnUpdate()
|
||||
{
|
||||
UpdateManager.UpdateProcedureCheck();
|
||||
StatTracker.CheckIn();
|
||||
if (Backups.IsBackupTime)
|
||||
Backups.Backup();
|
||||
//call these every second, not every update
|
||||
|
|
@ -564,7 +620,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (player.TileKillThreshold >= Config.TileKillThreshold)
|
||||
{
|
||||
player.Disable("Reached TileKill threshold");
|
||||
player.Disable("Reached TileKill threshold.");
|
||||
TSPlayer.Server.RevertTiles(player.TilesDestroyed);
|
||||
player.TilesDestroyed.Clear();
|
||||
}
|
||||
|
|
@ -579,7 +635,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (player.TilePlaceThreshold >= Config.TilePlaceThreshold)
|
||||
{
|
||||
player.Disable("Reached TilePlace threshold");
|
||||
player.Disable("Reached TilePlace threshold.");
|
||||
TSPlayer.Server.RevertTiles(player.TilesCreated);
|
||||
player.TilesCreated.Clear();
|
||||
}
|
||||
|
|
@ -590,7 +646,7 @@ namespace TShockAPI
|
|||
}
|
||||
if (player.TileLiquidThreshold >= Config.TileLiquidThreshold)
|
||||
{
|
||||
player.Disable("Reached TileLiquid threshold");
|
||||
player.Disable("Reached TileLiquid threshold.");
|
||||
}
|
||||
if (player.TileLiquidThreshold > 0)
|
||||
{
|
||||
|
|
@ -598,7 +654,7 @@ namespace TShockAPI
|
|||
}
|
||||
if (player.ProjectileThreshold >= Config.ProjectileThreshold)
|
||||
{
|
||||
player.Disable("Reached Projectile threshold");
|
||||
player.Disable("Reached projectile threshold.");
|
||||
}
|
||||
if (player.ProjectileThreshold > 0)
|
||||
{
|
||||
|
|
@ -614,7 +670,7 @@ namespace TShockAPI
|
|||
if (!player.Group.HasPermission(Permissions.ignorestackhackdetection) && item.stack > item.maxStack &&
|
||||
item.type != 0)
|
||||
{
|
||||
check = "Remove Item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack;
|
||||
check = "Remove item " + item.name + " (" + item.stack + ") exceeds max stack of " + item.maxStack;
|
||||
}
|
||||
}
|
||||
player.IgnoreActionsForCheating = check;
|
||||
|
|
@ -625,7 +681,7 @@ namespace TShockAPI
|
|||
{
|
||||
player.SetBuff(30, 120); //Bleeding
|
||||
player.SetBuff(36, 120); //Broken Armor
|
||||
check = "Remove Armor/Accessory " + item.name;
|
||||
check = "Remove armor/accessory " + item.name;
|
||||
}
|
||||
}
|
||||
player.IgnoreActionsForDisabledArmor = check;
|
||||
|
|
@ -776,12 +832,9 @@ namespace TShockAPI
|
|||
|
||||
if (tsplr != null && tsplr.ReceivedInfo)
|
||||
{
|
||||
if (!tsplr.SilentKickInProgress || tsplr.State > 1)
|
||||
if (!tsplr.SilentKickInProgress && tsplr.State >= 3)
|
||||
{
|
||||
if (tsplr.State >= 2)
|
||||
{
|
||||
Utils.Broadcast(tsplr.Name + " left", Color.Yellow);
|
||||
}
|
||||
Utils.Broadcast(tsplr.Name + " left", Color.Yellow);
|
||||
}
|
||||
Log.Info(string.Format("{0} disconnected.", tsplr.Name));
|
||||
|
||||
|
|
@ -841,7 +894,7 @@ namespace TShockAPI
|
|||
}
|
||||
else if (tsplr.mute)
|
||||
{
|
||||
tsplr.SendMessage("You are muted!");
|
||||
tsplr.SendErrorMessage("You are muted!");
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -874,11 +927,11 @@ namespace TShockAPI
|
|||
if (player != null && player.Active)
|
||||
{
|
||||
count++;
|
||||
TSPlayer.Server.SendMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
||||
TSPlayer.Server.SendInfoMessage(string.Format("{0} ({1}) [{2}] <{3}>", player.Name, player.IP,
|
||||
player.Group.Name, player.UserAccountName));
|
||||
}
|
||||
}
|
||||
TSPlayer.Server.SendMessage(string.Format("{0} players connected.", count));
|
||||
TSPlayer.Server.SendInfoMessage(string.Format("{0} players connected.", count));
|
||||
}
|
||||
else if (text == "autosave")
|
||||
{
|
||||
|
|
@ -959,7 +1012,7 @@ namespace TShockAPI
|
|||
|
||||
if (Config.PvPMode == "always" && !player.TPlayer.hostile)
|
||||
{
|
||||
player.SendMessage("PvP is forced! Enable PvP else you can't move or do anything!", Color.Red);
|
||||
player.SendMessage("PvP is forced! Enable PvP else you can't do anything!", Color.Red);
|
||||
}
|
||||
|
||||
if (!player.IsLoggedIn)
|
||||
|
|
@ -967,7 +1020,7 @@ namespace TShockAPI
|
|||
if (Config.ServerSideInventory)
|
||||
{
|
||||
player.SendMessage(
|
||||
player.IgnoreActionsForInventory = "Server Side Inventory is enabled! Please /register or /login to play!",
|
||||
player.IgnoreActionsForInventory = "Server side inventory is enabled! Please /register or /login to play!",
|
||||
Color.Red);
|
||||
player.LoginHarassed = true;
|
||||
}
|
||||
|
|
@ -1184,22 +1237,22 @@ namespace TShockAPI
|
|||
switch (random)
|
||||
{
|
||||
case 0:
|
||||
Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount));
|
||||
Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount), Color.Green);
|
||||
break;
|
||||
case 1:
|
||||
Utils.Broadcast(string.Format("Fatality! {0} goblins killed!", KillCount));
|
||||
Utils.Broadcast(string.Format("Fatality! {0} goblins killed!", KillCount), Color.Green);
|
||||
break;
|
||||
case 2:
|
||||
Utils.Broadcast(string.Format("Number of 'noobs' killed to date: {0}", KillCount));
|
||||
Utils.Broadcast(string.Format("Number of 'noobs' killed to date: {0}", KillCount), Color.Green);
|
||||
break;
|
||||
case 3:
|
||||
Utils.Broadcast(string.Format("Duke Nukem would be proud. {0} goblins killed.", KillCount));
|
||||
Utils.Broadcast(string.Format("Duke Nukem would be proud. {0} goblins killed.", KillCount), Color.Green);
|
||||
break;
|
||||
case 4:
|
||||
Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount));
|
||||
Utils.Broadcast(string.Format("You call that a lot? {0} goblins killed!", KillCount), Color.Green);
|
||||
break;
|
||||
case 5:
|
||||
Utils.Broadcast(string.Format("{0} copies of Call of Duty smashed.", KillCount));
|
||||
Utils.Broadcast(string.Format("{0} copies of Call of Duty smashed.", KillCount), Color.Green);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1256,6 +1309,7 @@ namespace TShockAPI
|
|||
{
|
||||
if (TShock.Config.AllowIce && actionType != 1)
|
||||
{
|
||||
|
||||
foreach (Point p in player.IceTiles)
|
||||
{
|
||||
if (p.X == tileX && p.Y == tileY && (Main.tile[p.X, p.Y].type == 0 || Main.tile[p.X, p.Y].type == 127))
|
||||
|
|
@ -1264,11 +1318,12 @@ namespace TShockAPI
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000){
|
||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
||||
player.BPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
|
||||
}
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000){
|
||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
||||
player.BPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1278,30 +1333,33 @@ namespace TShockAPI
|
|||
return false;
|
||||
}
|
||||
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000){
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.BPm) > 2000){
|
||||
player.SendMessage("You do not have permission to build!", Color.Red);
|
||||
player.BPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
player.BPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
if (!player.Group.HasPermission(Permissions.editspawn) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
Regions.InArea(tileX, tileY))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000){
|
||||
player.SendMessage("Region protected from changes.", Color.Red);
|
||||
player.RPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||
{
|
||||
player.SendMessage("This region is protected from changes.", Color.Red);
|
||||
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Config.DisableBuild)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.editspawn))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000){
|
||||
player.SendMessage("World protected from changes.", Color.Red);
|
||||
player.SendMessage("The world is protected from changes.", Color.Red);
|
||||
player.WPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
|
||||
}
|
||||
|
|
@ -1316,7 +1374,7 @@ namespace TShockAPI
|
|||
if (flag)
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 2000){
|
||||
player.SendMessage("Spawn protected from changes.", Color.Red);
|
||||
player.SendMessage("Spawn is protected from changes.", Color.Red);
|
||||
player.SPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1337,25 +1395,26 @@ namespace TShockAPI
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!player.Group.HasPermission(Permissions.editspawn) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
Regions.InArea(tileX, tileY))
|
||||
{
|
||||
|
||||
if (!player.Group.HasPermission(Permissions.editspawn) && !Regions.CanBuild(tileX, tileY, player) &&
|
||||
Regions.InArea(tileX, tileY))
|
||||
{
|
||||
|
||||
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000){
|
||||
player.SendMessage("Region protected from changes.", Color.Red);
|
||||
player.RPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.RPm) > 2000)
|
||||
{
|
||||
player.SendMessage("This region is protected from changes.", Color.Red);
|
||||
player.RPm = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Config.DisableBuild)
|
||||
{
|
||||
if (!player.Group.HasPermission(Permissions.editspawn))
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.WPm) > 2000){
|
||||
player.SendMessage("World protected from changes.", Color.Red);
|
||||
player.SendMessage("The world is protected from changes.", Color.Red);
|
||||
player.WPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -1369,7 +1428,7 @@ namespace TShockAPI
|
|||
if (flag)
|
||||
{
|
||||
if (((DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - player.SPm) > 1000){
|
||||
player.SendMessage("Spawn protected from changes.", Color.Red);
|
||||
player.SendMessage("Spawn is protected from changes.", Color.Red);
|
||||
player.SPm=DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
|
||||
}
|
||||
|
|
@ -1396,12 +1455,12 @@ namespace TShockAPI
|
|||
return (float) Math.Sqrt(num3);
|
||||
}
|
||||
|
||||
public static bool HackedHealth(TSPlayer player)
|
||||
public static bool HackedStats(TSPlayer player)
|
||||
{
|
||||
return (player.TPlayer.statManaMax > 400) ||
|
||||
(player.TPlayer.statMana > 400) ||
|
||||
(player.TPlayer.statLifeMax > 400) ||
|
||||
(player.TPlayer.statLife > 400);
|
||||
return (player.TPlayer.statManaMax > TShock.Config.MaxMana) ||
|
||||
(player.TPlayer.statMana > TShock.Config.MaxMana) ||
|
||||
(player.TPlayer.statLifeMax > TShock.Config.MaxHealth) ||
|
||||
(player.TPlayer.statLife > TShock.Config.MaxHealth);
|
||||
}
|
||||
|
||||
public static bool HackedInventory(TSPlayer player)
|
||||
|
|
@ -1458,7 +1517,7 @@ namespace TShockAPI
|
|||
|
||||
if (player.TPlayer.statLifeMax > playerData.maxHealth)
|
||||
{
|
||||
player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server",
|
||||
player.SendMessage("Error: Your max health exceeded (" + playerData.maxHealth + ") which is stored on server.",
|
||||
Color.Cyan);
|
||||
check = false;
|
||||
}
|
||||
|
|
@ -1498,7 +1557,7 @@ namespace TShockAPI
|
|||
item.AffixName();
|
||||
player.SendMessage(
|
||||
player.IgnoreActionsForInventory =
|
||||
"Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" +
|
||||
"Your item (" + item.name + ") (" + inventory[i].stack + ") needs to have its stack size decreased to (" +
|
||||
playerData.inventory[i].stack + ").", Color.Cyan);
|
||||
check = false;
|
||||
}
|
||||
|
|
@ -1535,7 +1594,7 @@ namespace TShockAPI
|
|||
item.AffixName();
|
||||
player.SendMessage(
|
||||
player.IgnoreActionsForInventory =
|
||||
"Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have it's stack decreased to (" +
|
||||
"Your armor (" + item.name + ") (" + inventory[i].stack + ") needs to have its stack size decreased to (" +
|
||||
playerData.inventory[i].stack + ").", Color.Cyan);
|
||||
check = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,30 +61,27 @@
|
|||
<HintPath>..\SqlBins\MySql.Data.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Web, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\SqlBins\MySql.Web.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>.\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="TerrariaServer, Version=1.0.4.0, Culture=neutral, processorArchitecture=x86">
|
||||
<Reference Include="TerrariaServer, Version=0.0.0.0, Culture=neutral, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<ExecutableExtension>.exe</ExecutableExtension>
|
||||
<HintPath>..\TerrariaServerBins\TerrariaServer.exe</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackupManager.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="Hooks\GeneralHooks.cs" />
|
||||
<Compile Include="Hooks\PlayerHooks.cs" />
|
||||
<Compile Include="PaginationTools.cs" />
|
||||
<Compile Include="PluginUpdater\PluginUpdaterThread.cs" />
|
||||
<Compile Include="PluginUpdater\PluginVersionCheck.cs" />
|
||||
<Compile Include="PluginUpdater\VersionInfo.cs" />
|
||||
<Compile Include="Rest\RestPermissions.cs" />
|
||||
<Compile Include="SaveManager.cs" />
|
||||
<Compile Include="DB\BanManager.cs" />
|
||||
<Compile Include="DB\InventoryManager.cs" />
|
||||
|
|
@ -114,11 +111,10 @@
|
|||
<Compile Include="Net\ProjectileRemoveMsg.cs" />
|
||||
<Compile Include="Net\SpawnMsg.cs" />
|
||||
<Compile Include="Net\WorldInfoMsg.cs" />
|
||||
<Compile Include="DB\RegionManager.cs" />
|
||||
<Compile Include="PacketBufferer.cs" />
|
||||
<Compile Include="Permissions.cs" />
|
||||
<Compile Include="RconHandler.cs" />
|
||||
<Compile Include="DB\RememberPosManager.cs" />
|
||||
<Compile Include="DB\RememberedPosManager.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
|
|
@ -130,7 +126,6 @@
|
|||
<Compile Include="Rest\RestObject.cs" />
|
||||
<Compile Include="Rest\RestVerbs.cs" />
|
||||
<Compile Include="Rest\SecureRest.cs" />
|
||||
<Compile Include="StatTracker.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="TShock.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
|
|
@ -184,7 +179,8 @@
|
|||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>"$(ProjectDir)postbuild.bat"</PostBuildEvent>
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
|
|
@ -198,4 +194,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
extensions: .cs
|
||||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
TShock, a server mod for Terraria
|
||||
Copyright (C) 2011-2012 The TShock Team
|
||||
Copyright (C) 2011-2013 Nyx Studios (fka. The TShock Team)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -15,6 +15,7 @@ GNU General Public License for more details.
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
|
@ -33,12 +34,12 @@ namespace TShockAPI
|
|||
public class Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Document me
|
||||
/// The lowest id for a prefix.
|
||||
/// </summary>
|
||||
private const int FirstItemPrefix = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Document me
|
||||
/// The highest id for a prefix.
|
||||
/// </summary>
|
||||
private const int LastItemPrefix = 83;
|
||||
|
||||
|
|
@ -183,6 +184,7 @@ namespace TShockAPI
|
|||
/// Broadcasts a message to all players
|
||||
/// </summary>
|
||||
/// <param name="msg">string message</param>
|
||||
[Obsolete("Use TSPlayer.All and send a message via that method rather than using Broadcast.")]
|
||||
public void Broadcast(string msg)
|
||||
{
|
||||
Broadcast(msg, Color.Green);
|
||||
|
|
@ -211,23 +213,24 @@ namespace TShockAPI
|
|||
public void Broadcast(int ply, string msg, byte red, byte green, byte blue)
|
||||
{
|
||||
TSPlayer.All.SendMessageFromPlayer(msg, red, green, blue, ply);
|
||||
TSPlayer.Server.SendMessage(msg, red, green, blue);
|
||||
Log.Info(string.Format("Broadcast: {0}", msg));
|
||||
TSPlayer.Server.SendMessage(Main.player[ply].name + ": " + msg, red, green, blue);
|
||||
Log.Info(string.Format("Broadcast: {0}", Main.player[ply].name + ": " + msg));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends message to all users with 'logs' permission.
|
||||
/// Sends message to all players with 'logs' permission.
|
||||
/// </summary>
|
||||
/// <param name="log">Message to send</param>
|
||||
/// <param name="color">Color of the message</param>
|
||||
public void SendLogs(string log, Color color)
|
||||
/// <param name="excludedPlayer">The player to not send the message to.</param>
|
||||
public void SendLogs(string log, Color color, TSPlayer excludedPlayer = null)
|
||||
{
|
||||
Log.Info(log);
|
||||
TSPlayer.Server.SendMessage(log, color);
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player != null && player.Active && player.Group.HasPermission(Permissions.logs) && player.DisplayLogs &&
|
||||
TShock.Config.DisableSpewLogs == false)
|
||||
if (player != null && player != excludedPlayer && player.Active && player.Group.HasPermission(Permissions.logs) &&
|
||||
player.DisplayLogs && TShock.Config.DisableSpewLogs == false)
|
||||
player.SendMessage(log, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -242,41 +245,38 @@ namespace TShockAPI
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a TSPlayer based on name or id
|
||||
/// Finds a TSPlayer based on name or ID
|
||||
/// </summary>
|
||||
/// <param name="ply">Player name</param>
|
||||
/// <param name="plr">Player name or ID</param>
|
||||
/// <returns></returns>
|
||||
public List<TSPlayer> FindPlayer(string ply)
|
||||
public List<TSPlayer> FindPlayer(string plr)
|
||||
{
|
||||
var found = new List<TSPlayer>();
|
||||
// Avoid errors caused by null search
|
||||
if (null == ply)
|
||||
if (plr == null)
|
||||
return found;
|
||||
ply = ply.ToLower();
|
||||
|
||||
byte plrID;
|
||||
if (byte.TryParse(plr, out plrID))
|
||||
{
|
||||
TSPlayer player = TShock.Players[plrID];
|
||||
if (player != null && player.Active)
|
||||
{
|
||||
return new List<TSPlayer> { player };
|
||||
}
|
||||
}
|
||||
|
||||
string plrLower = plr.ToLower();
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
{
|
||||
if (player == null)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
if (Convert.ToInt32(ply) == player.Index && player.Active)
|
||||
{
|
||||
return new List<TSPlayer> { player };
|
||||
}
|
||||
}
|
||||
// ReSharper disable EmptyGeneralCatchClause
|
||||
catch (Exception e)
|
||||
// ReSharper restore EmptyGeneralCatchClause
|
||||
{
|
||||
// Conversion failed
|
||||
}
|
||||
|
||||
string name = player.Name.ToLower();
|
||||
if (name.Equals(ply))
|
||||
return new List<TSPlayer> {player};
|
||||
if (name.Contains(ply))
|
||||
found.Add(player);
|
||||
if (player != null)
|
||||
{
|
||||
// Must be an EXACT match
|
||||
if (player.Name == plr)
|
||||
return new List<TSPlayer> { player };
|
||||
if (player.Name.ToLower().StartsWith(plrLower))
|
||||
found.Add(player);
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
@ -315,13 +315,13 @@ namespace TShockAPI
|
|||
/// <param name="tileX">Location X</param>
|
||||
/// <param name="tileY">Location Y</param>
|
||||
/// <returns>If the tile is valid</returns>
|
||||
private bool TileValid(int tileX, int tileY)
|
||||
public bool TileValid(int tileX, int tileY)
|
||||
{
|
||||
return tileX >= 0 && tileX <= Main.maxTilesX && tileY >= 0 && tileY <= Main.maxTilesY;
|
||||
return tileX >= 0 && tileX < Main.maxTilesX && tileY >= 0 && tileY < Main.maxTilesY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears a tile
|
||||
/// Checks to see if the tile is clear.
|
||||
/// </summary>
|
||||
/// <param name="tileX">Location X</param>
|
||||
/// <param name="tileY">Location Y</param>
|
||||
|
|
@ -341,6 +341,8 @@ namespace TShockAPI
|
|||
int type = -1;
|
||||
if (int.TryParse(idOrName, out type))
|
||||
{
|
||||
if (type >= Main.maxItemTypes)
|
||||
return new List<Item>();
|
||||
return new List<Item> {GetItemById(type)};
|
||||
}
|
||||
return GetItemByName(idOrName);
|
||||
|
|
@ -365,30 +367,16 @@ namespace TShockAPI
|
|||
/// <returns>List of Items</returns>
|
||||
public List<Item> GetItemByName(string name)
|
||||
{
|
||||
//Method #1 - must be exact match, allows support for different pickaxes/hammers/swords etc
|
||||
for (int i = 1; i < Main.maxItemTypes; i++)
|
||||
{
|
||||
Item item = new Item();
|
||||
item.SetDefaults(name);
|
||||
if (item.name == name)
|
||||
return new List<Item> {item};
|
||||
}
|
||||
//Method #2 - allows impartial matching
|
||||
var found = new List<Item>();
|
||||
Item item = new Item();
|
||||
string nameLower = name.ToLower();
|
||||
for (int i = -24; i < Main.maxItemTypes; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Item item = new Item();
|
||||
item.netDefaults(i);
|
||||
if (item.name.ToLower() == name.ToLower())
|
||||
return new List<Item> {item};
|
||||
if (item.name.ToLower().StartsWith(name.ToLower()))
|
||||
found.Add(item);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
item.netDefaults(i);
|
||||
if (item.name.ToLower() == nameLower)
|
||||
return new List<Item> {item};
|
||||
if (item.name.ToLower().StartsWith(nameLower))
|
||||
found.Add((Item)item.Clone());
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
@ -403,7 +391,9 @@ namespace TShockAPI
|
|||
int type = -1;
|
||||
if (int.TryParse(idOrName, out type))
|
||||
{
|
||||
return new List<NPC> {GetNPCById(type)};
|
||||
if (type >= Main.maxNPCTypes)
|
||||
return new List<NPC>();
|
||||
return new List<NPC> { GetNPCById(type) };
|
||||
}
|
||||
return GetNPCByName(idOrName);
|
||||
}
|
||||
|
|
@ -427,24 +417,16 @@ namespace TShockAPI
|
|||
/// <returns>List of matching NPCs</returns>
|
||||
public List<NPC> GetNPCByName(string name)
|
||||
{
|
||||
//Method #1 - must be exact match, allows support for different coloured slimes
|
||||
var found = new List<NPC>();
|
||||
NPC npc = new NPC();
|
||||
string nameLower = name.ToLower();
|
||||
for (int i = -17; i < Main.maxNPCTypes; i++)
|
||||
{
|
||||
NPC npc = new NPC();
|
||||
npc.SetDefaults(name);
|
||||
if (npc.name == name)
|
||||
return new List<NPC> {npc};
|
||||
}
|
||||
//Method #2 - allows impartial matching
|
||||
var found = new List<NPC>();
|
||||
for (int i = 1; i < Main.maxNPCTypes; i++)
|
||||
{
|
||||
NPC npc = new NPC();
|
||||
npc.netDefaults(i);
|
||||
if (npc.name.ToLower() == name.ToLower())
|
||||
return new List<NPC> {npc};
|
||||
if (npc.name.ToLower().StartsWith(name.ToLower()))
|
||||
found.Add(npc);
|
||||
if (npc.name.ToLower() == nameLower)
|
||||
return new List<NPC> { npc };
|
||||
if (npc.name.ToLower().StartsWith(nameLower))
|
||||
found.Add((NPC)npc.Clone());
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
@ -476,15 +458,16 @@ namespace TShockAPI
|
|||
/// <returns>Matching list of buff ids</returns>
|
||||
public List<int> GetBuffByName(string name)
|
||||
{
|
||||
string nameLower = name.ToLower();
|
||||
for (int i = 1; i < Main.maxBuffs; i++)
|
||||
{
|
||||
if (Main.buffName[i].ToLower() == name)
|
||||
if (Main.buffName[i].ToLower() == nameLower)
|
||||
return new List<int> {i};
|
||||
}
|
||||
var found = new List<int>();
|
||||
for (int i = 1; i < Main.maxBuffs; i++)
|
||||
{
|
||||
if (Main.buffName[i].ToLower().StartsWith(name.ToLower()))
|
||||
if (Main.buffName[i].ToLower().StartsWith(nameLower))
|
||||
found.Add(i);
|
||||
}
|
||||
return found;
|
||||
|
|
@ -517,32 +500,12 @@ namespace TShockAPI
|
|||
var found = new List<int>();
|
||||
for (int i = FirstItemPrefix; i <= LastItemPrefix; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
item.prefix = (byte)i;
|
||||
string trimmed = item.AffixName().Trim();
|
||||
if (trimmed == name)
|
||||
{
|
||||
// Exact match
|
||||
found.Add(i);
|
||||
return found;
|
||||
}
|
||||
else
|
||||
{
|
||||
string trimmedLower = trimmed.ToLower();
|
||||
if (trimmedLower == lowerName)
|
||||
{
|
||||
// Exact match (caseinsensitive)
|
||||
found.Add(i);
|
||||
return found;
|
||||
}
|
||||
else if (trimmedLower.StartsWith(lowerName)) // Partial match
|
||||
found.Add(i);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
item.prefix = (byte)i;
|
||||
string prefixName = item.AffixName().Trim().ToLower();
|
||||
if (prefixName == lowerName)
|
||||
return new List<int>() { i };
|
||||
else if (prefixName.StartsWith(lowerName)) // Partial match
|
||||
found.Add(i);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
|
@ -599,6 +562,36 @@ namespace TShockAPI
|
|||
Netplay.disconnect = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the server after kicking all players with a reason message, and optionally saving the world then attempts to
|
||||
/// restart it.
|
||||
/// </summary>
|
||||
/// <param name="save">bool perform a world save before stop (default: true)</param>
|
||||
/// <param name="reason">string reason (default: "Server shutting down!")</param>
|
||||
public void RestartServer(bool save = true, string reason = "Server shutting down!")
|
||||
{
|
||||
if (TShock.Config.ServerSideInventory)
|
||||
foreach (TSPlayer player in TShock.Players)
|
||||
if (player != null && player.IsLoggedIn && !player.IgnoreActionsForClearingTrashCan)
|
||||
TShock.InventoryDB.InsertPlayerData(player);
|
||||
|
||||
StopServer(true, reason);
|
||||
System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reloads all configuration settings, groups, regions and raises the reload event.
|
||||
/// </summary>
|
||||
public void Reload(TSPlayer player)
|
||||
{
|
||||
FileTools.SetupConfig();
|
||||
TShock.HandleCommandLinePostConfigLoad(Environment.GetCommandLineArgs());
|
||||
TShock.Groups.LoadPermisions();
|
||||
TShock.Regions.ReloadAllRegions();
|
||||
Hooks.GeneralHooks.OnReloadEvent(player);
|
||||
}
|
||||
|
||||
#if COMPAT_SIGS
|
||||
[Obsolete("This method is for signature compatibility for external code only")]
|
||||
public void ForceKick(TSPlayer player, string reason)
|
||||
|
|
@ -649,9 +642,9 @@ namespace TShockAPI
|
|||
if (!silent)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(adminUserName))
|
||||
Broadcast(string.Format("{0} was {1}kicked for {2}", playerName, verb, reason.ToLower()));
|
||||
Broadcast(string.Format("{0} was {1}kicked for {2}", playerName, verb, reason.ToLower()), Color.Green);
|
||||
else
|
||||
Broadcast(string.Format("{0} {1}kicked {2} for {3}", adminUserName, verb, playerName, reason.ToLower()));
|
||||
Broadcast(string.Format("{0} {1}kicked {2} for {3}", adminUserName, verb, playerName, reason.ToLower()), Color.Green);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -685,9 +678,9 @@ namespace TShockAPI
|
|||
Log.ConsoleInfo(string.Format("Banned {0} for : {1}", playerName, reason));
|
||||
string verb = force ? "force " : "";
|
||||
if (string.IsNullOrWhiteSpace(adminUserName))
|
||||
Broadcast(string.Format("{0} was {1}banned for {1}", playerName, verb, reason.ToLower()));
|
||||
Broadcast(string.Format("{0} was {1}banned for {2}", playerName, verb, reason.ToLower()));
|
||||
else
|
||||
Broadcast(string.Format("{0} {1}banned {1} for {2}", adminUserName, verb, playerName, reason.ToLower()));
|
||||
Broadcast(string.Format("{0} {1}banned {2} for {3}", adminUserName, verb, playerName, reason.ToLower()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -770,8 +763,14 @@ namespace TShockAPI
|
|||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default hashing algorithm.
|
||||
/// </summary>
|
||||
public string HashAlgo = "sha512";
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary of hashing algortihms and an implementation object.
|
||||
/// </summary>
|
||||
public readonly Dictionary<string, Func<HashAlgorithm>> HashTypes = new Dictionary<string, Func<HashAlgorithm>>
|
||||
{
|
||||
{"sha512", () => new SHA512Managed()},
|
||||
|
|
@ -874,5 +873,25 @@ namespace TShockAPI
|
|||
}
|
||||
return new string(returnstr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates boundary points of the given region's rectangle.
|
||||
/// </summary>
|
||||
/// <param name="regionArea">The region's area to enumerate through.</param>
|
||||
/// <returns>The enumerated boundary points.</returns>
|
||||
public IEnumerable<Point> EnumerateRegionBoundaries(Rectangle regionArea)
|
||||
{
|
||||
for (int x = 0; x < regionArea.Width + 1; x++)
|
||||
{
|
||||
yield return new Point(regionArea.Left + x, regionArea.Top);
|
||||
yield return new Point(regionArea.Left + x, regionArea.Bottom);
|
||||
}
|
||||
|
||||
for (int y = 1; y < regionArea.Height; y++)
|
||||
{
|
||||
yield return new Point(regionArea.Left, regionArea.Top + y);
|
||||
yield return new Point(regionArea.Right, regionArea.Top + y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue