Fix various things.

This commit is contained in:
SilicaAndPina 2020-12-28 14:42:14 +13:00
parent 46c45eb8bb
commit 8a6a5ef36c
34 changed files with 1058 additions and 24 deletions

View file

@ -43,6 +43,19 @@ namespace HISP.Game.Chat
return false;
}
}
if (args[0] == "QUEST")
{
int questId = 0;
try
{
questId = int.Parse(args[1]);
Quest.ActivateQuest(user, Quest.GetQuestById(questId));
}
catch (Exception)
{
return false;
}
}
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatAdminCommandCompleteMessage(message.Substring(1)), PacketBuilder.CHAT_BOTTOM_LEFT);
user.LoggedinClient.SendPacket(chatPacket);

View file

@ -1,4 +1,5 @@
using HISP.Server;
using System;
namespace HISP.Game
{
@ -173,6 +174,12 @@ namespace HISP.Game
public static string GameHighScoreHeaderFormat;
public static string GameHighScoreFormat;
// Awards
public static string AwardHeader;
public static string NoAwards;
public static string AwardFormat;
// Shop
public static string ThingsIAmSelling;
@ -240,6 +247,11 @@ namespace HISP.Game
// Click
public static string NothingInterestingHere;
public static string FormatAwardEntry(int iconId, string title, int moneyBonus)
{
return AwardFormat.Replace("%ICON%", iconId.ToString()).Replace("%NAME%", title).Replace("%BONUS%", moneyBonus.ToString("N0"));
}
public static string FormatBestTimeHeader(string gameName)
{
return GameBestTimeHeaderFormat.Replace("%GAMETITLE%", gameName);
@ -278,7 +290,9 @@ namespace HISP.Game
}
public static string FormatQuestFooter(int totalQuestsComplete, int totalQuests, int questPoints, int totalQuestPoints)
{
return QuestFooterFormat.Replace("%TOTALCOMPLETED%", totalQuestsComplete.ToString("N0")).Replace("%TOTALQUESTS%", totalQuests.ToString("N0")).Replace("%TOTALPERCENT%", ((totalQuestsComplete / totalQuests) * 100).ToString()).Replace("%YOURQP%", questPoints.ToString("N0")).Replace("%YOURQP%", totalQuestPoints.ToString("N0")).Replace("%QPERCENT%", ((totalQuestsComplete / totalQuests) * 100).ToString()).Replace("%MAXQP%", totalQuestPoints.ToString("N0"));
int questsComplete = Convert.ToInt32(Math.Floor(((decimal)totalQuestsComplete / (decimal)totalQuests) * (decimal)100.0));
int questPointsComplete = Convert.ToInt32(Math.Floor(((decimal)questPoints / (decimal)totalQuestPoints) * (decimal)100.0));
return QuestFooterFormat.Replace("%TOTALCOMPLETED%", totalQuestsComplete.ToString("N0")).Replace("%TOTALQUESTS%", totalQuests.ToString("N0")).Replace("%TOTALPERCENT%", questsComplete.ToString()).Replace("%YOURQP%", questPoints.ToString("N0")).Replace("%YOURQP%", totalQuestPoints.ToString("N0")).Replace("%QPERCENT%", questPointsComplete.ToString()).Replace("%MAXQP%", totalQuestPoints.ToString("N0"));
}
public static string FormatQuestLogQuest(string questTitle, int questPoints, string difficulty, string completionStatus)
{
@ -429,7 +443,7 @@ namespace HISP.Game
}
public static string FormatShopEntry(int iconid, string count, string name, int price)
{
return ShopEntryFormat.Replace("%ICONID%", iconid.ToString()).Replace("%COUNT%", count).Replace("%TITLE%", name).Replace("%PRICE%", price.ToString());
return ShopEntryFormat.Replace("%ICONID%", iconid.ToString()).Replace("%COUNT%", count).Replace("%TITLE%", name).Replace("%PRICE%", price.ToString("N0"));
}
public static string FormatWearButton(int randomId)
{

View file

@ -323,7 +323,6 @@ namespace HISP.Game
Transport.TransportLocation transportLocation = Transport.GetTransportLocation(transportLocationId);
message += Messages.FormatTransportMessage(transportLocation.Type, transportLocation.LocationTitle, transportLocation.Cost, transportLocation.Id, transportLocation.GotoX, transportLocation.GotoY);
}
message += "^R1";
message += Messages.ExitThisPlace;
message += Messages.MetaTerminator;
return message;
@ -358,6 +357,22 @@ namespace HISP.Game
return message;
}
public static string BuildAwardList(User user)
{
string message = Messages.AwardHeader;
if (user.Awards.AwardsEarned.Length <= 0)
message += Messages.NoAwards;
else
foreach(Award.AwardEntry award in user.Awards.AwardsEarned)
message += Messages.FormatAwardEntry(award.IconId, award.Title, award.MoneyBonus);
message += Messages.BackToMap;
message += Messages.MetaTerminator;
return message;
}
public static string BuildQuestLog(User user)
{
string message = "";
@ -382,14 +397,8 @@ namespace HISP.Game
message += Messages.FormatQuestLogQuest(quest.Title, quest.QuestPointsEarned, quest.Difficulty, fmsg);
}
int totalComplete = 0;
int totalQuestPoints = 0;
foreach(Quest.QuestEntry quest in questList)
{
if(user.Quests.GetTrackedQuestAmount(quest.Id) > 0)
totalComplete++;
totalQuestPoints += quest.QuestPointsEarned;
}
int totalComplete = Quest.GetTotalQuestsComplete(user);
int totalQuestPoints = Quest.GetTotalQuestPoints();
message += Messages.FormatQuestFooter(totalComplete, questList.Length, user.QuestPoints, totalQuestPoints);
message += Messages.BackToMap;
@ -434,7 +443,7 @@ namespace HISP.Game
if (TileCode == "TRANSPORT")
{
Transport.TransportPoint point = Transport.GetTransportPoint(specialTile.X, specialTile.Y);
message += Meta.BuildTransportInfo(point) + "^R1";
message += Meta.BuildTransportInfo(point);
}
if (TileCode == "STRAWPILE")

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using HISP.Player;
using HISP.Server;
@ -70,6 +71,21 @@ namespace HISP.Game
}
return totalQp;
}
public static int GetTotalQuestsComplete(User user)
{
QuestEntry[] questList = GetPublicQuestList();
int totalComplete = 0;
foreach (QuestEntry quest in questList)
{
if (user.Quests.GetTrackedQuestAmount(quest.Id) > 0)
totalComplete++;
}
return totalComplete;
}
public static QuestEntry[] GetPublicQuestList()
{
QuestEntry[] quests = QuestList.OrderBy(o => o.Title).ToArray();
@ -104,6 +120,11 @@ namespace HISP.Game
}
// Check if user has award unlocked
if(quest.AwardRequired != 0)
if (!user.Awards.HasAward(Award.GetAwardById(quest.AwardRequired)))
return false;
// Check if i have required items
foreach (QuestItemInfo itemInfo in quest.ItemsRequired)
{
@ -180,6 +201,26 @@ namespace HISP.Game
byte[] ChatPacket = PacketBuilder.CreateChat(quest.SuccessMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
user.LoggedinClient.SendPacket(ChatPacket);
}
// Check if award unlocked
int questPointsPercent = Convert.ToInt32(Math.Floor(((decimal)user.QuestPoints / (decimal)GetTotalQuestPoints()) * (decimal)100.0));
if (questPointsPercent >= 25)
user.Awards.AddAward(Award.GetAwardById(1)); // 25% Quest Completion Award.
if (questPointsPercent >= 50)
user.Awards.AddAward(Award.GetAwardById(2)); // 50% Quest Completion Award.
if (questPointsPercent >= 75)
user.Awards.AddAward(Award.GetAwardById(3)); // 75% Quest Completion Award.
if (questPointsPercent >= 100)
user.Awards.AddAward(Award.GetAwardById(4)); // 100% Quest Completion Award.
// Is cloud isles quest?
if(quest.Id == 1373)
{
byte[] swfLoadPacket = PacketBuilder.CreateSwfModulePacket("ballooncutscene", PacketBuilder.PACKET_SWF_CUTSCENE);
user.LoggedinClient.SendPacket(swfLoadPacket);
}
return true;
}
else {
@ -193,6 +234,7 @@ namespace HISP.Game
}
return false;
};
}
public static bool DoesQuestExist(int id)
{

View file

@ -81,6 +81,7 @@
<Compile Include="Game\Quest.cs" />
<Compile Include="Game\Shop.cs" />
<Compile Include="Game\Inventory\ShopInventory.cs" />
<Compile Include="Player\Award.cs" />
<Compile Include="Player\Equips\Jewelry.cs" />
<Compile Include="Player\Equips\CompetitionGear.cs" />
<Compile Include="Player\Highscore.cs" />

View file

@ -0,0 +1,97 @@
using HISP.Server;
using System;
using System.Collections.Generic;
namespace HISP.Player
{
class Award
{
public struct AwardEntry
{
public int Id;
public int Sort;
public string Title;
public int IconId;
public int MoneyBonus;
public string CompletionText;
public string Description;
}
public static AwardEntry[] GlobalAwardList;
public static AwardEntry GetAwardById(int id)
{
try
{
AwardEntry award = GlobalAwardList[id - 1];
if (award.Id == id)
return award;
}
catch (Exception) { };
foreach(AwardEntry award in GlobalAwardList)
{
if (award.Id == id)
return award;
}
throw new KeyNotFoundException("Award ID " + id + " Does not exist.");
}
private List<AwardEntry> awardsEarned;
private User baseUser;
public AwardEntry[] AwardsEarned
{
get
{
return awardsEarned.ToArray();
}
}
public bool HasAward(AwardEntry award)
{
foreach(AwardEntry awardEntry in AwardsEarned)
{
if (awardEntry.Id == award.Id)
return true;
}
return false;
}
public void AddAward(AwardEntry award,bool addToDatabase=true)
{
if (HasAward(award))
return;
if (addToDatabase)
{
Database.AddAward(baseUser.Id, award.Id);
baseUser.Money += award.MoneyBonus;
byte[] chatPacket = PacketBuilder.CreateChat(award.CompletionText, PacketBuilder.CHAT_BOTTOM_RIGHT);
baseUser.LoggedinClient.SendPacket(chatPacket);
}
awardsEarned.Add(award);
}
public Award(User user)
{
baseUser = user;
int[] awards = Database.GetAwards(user.Id);
awardsEarned = new List<AwardEntry>();
foreach (int awardid in awards)
{
AddAward(GetAwardById(awardid), false);
}
}
}
}

View file

@ -40,6 +40,7 @@ namespace HISP.Player
public Shop LastShoppedAt;
public PlayerQuests Quests;
public Highscore Highscores;
public Award Awards;
public int FreeMinutes
{
get
@ -374,7 +375,7 @@ namespace HISP.Player
Gender = Database.GetGender(UserId);
MailBox = new Mailbox(this);
Highscores = new Highscore(this);
Awards = new Award(this);
// Generate SecCodes

View file

@ -27,6 +27,7 @@ namespace HISP.Server
string TrackedQuest = "CREATE TABLE TrackedQuest(playerId INT, questId INT, timesCompleted INT)";
string OnlineUsers = "CREATE TABLE OnlineUsers(playerId INT, Admin TEXT(3), Moderator TEXT(3), Subscribed TEXT(3))";
string CompetitionGear = "CREATE TABLE CompetitionGear(playerId INT, headItem INT, bodyItem INT, legItem INT, feetItem INT)";
string Awards = "CREATE TABLE Awards(playerId INT, awardId INT)";
string Jewelry = "CREATE TABLE Jewelry(playerId INT, slot1 INT, slot2 INT, slot3 INT, slot4 INT)";
string Leaderboards = "CREATE TABLE Leaderboards(playerId INT, minigame TEXT(128), wins INT, looses INT, timesplayed INT, score INT, type TEXT(128))";
string DeleteOnlineUsers = "DELETE FROM OnlineUsers";
@ -97,6 +98,19 @@ namespace HISP.Server
Logger.WarnPrint(e.Message);
};
try
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = Awards;
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
catch (Exception e)
{
Logger.WarnPrint(e.Message);
};
try
{
@ -506,6 +520,48 @@ namespace HISP.Server
return timesComplete;
}
}
public static int[] GetAwards(int playerId)
{
List<int> awards = new List<int>();
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT awardId FROM Awards WHERE playerId=@playerId";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Prepare();
MySqlDataReader reader = sqlCommand.ExecuteReader();
while(reader.Read())
{
awards.Add(reader.GetInt32(0));
}
sqlCommand.Dispose();
return awards.ToArray();
}
}
public static void AddAward(int playerId, int awardId)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "INSERT INTO Awards VALUES(@playerId,@awardId)";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@awardId", awardId);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
return;
}
}
public static bool HasCompetitionGear(int playerId)
{

View file

@ -3,6 +3,7 @@ using System.IO;
using Newtonsoft.Json;
using HISP.Game;
using HISP.Game.Chat;
using HISP.Player;
namespace HISP.Server
{
@ -372,6 +373,27 @@ namespace HISP.Server
Logger.DebugPrint("Registered Shop ID: "+ shop.Id + " Selling items at " + shop.SellPricePercentage + "% and buying at " + shop.BuyPricePercentage);
}
// Register awards
int totalAwards = gameData.award_list.Count;
Award.GlobalAwardList = new Award.AwardEntry[totalAwards];
for (int i = 0; i < totalAwards; i++)
{
Award.AwardEntry award = new Award.AwardEntry();
award.Id = i+1;
award.Sort = gameData.award_list[i].sort_by;
award.Title = gameData.award_list[i].title;
award.IconId = gameData.award_list[i].icon_id;
award.MoneyBonus = gameData.award_list[i].earn_money;
award.CompletionText = gameData.award_list[i].on_complete_text;
award.Description = gameData.award_list[i].description;
Award.GlobalAwardList[i] = award;
Logger.DebugPrint("Registered Award ID: " + award.Id + " - " + award.Title);
}
Item.Present = gameData.item.special.present;
Item.MailMessage = gameData.item.special.mail_message;
Item.DorothyShoes = gameData.item.special.dorothy_shoes;
@ -562,6 +584,12 @@ namespace HISP.Server
Messages.GameBestTimeHeaderFormat = gameData.messages.meta.highscores.game_besttime_header;
Messages.GameBestTimeFormat = gameData.messages.meta.highscores.game_besttime_format;
// Awards
Messages.AwardHeader = gameData.messages.meta.awards_page.awards_header;
Messages.NoAwards = gameData.messages.meta.awards_page.no_awards;
Messages.AwardFormat = gameData.messages.meta.awards_page.award_format;
// Sec Codes
Messages.InvalidSecCodeError = gameData.messages.sec_code.invalid_sec_code;

View file

@ -161,6 +161,10 @@ namespace HISP.Server
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildMinigameRankingsForUser(sender.LoggedinUser));
sender.SendPacket(metaPacket);
break;
case 24:
metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildAwardList(sender.LoggedinUser));
sender.SendPacket(metaPacket);
break;
default:
Logger.ErrorPrint("Dynamic button #" + buttonId + " unknown...");
break;
@ -311,6 +315,45 @@ namespace HISP.Server
UpdateArea(sender);
UpdateUserInfo(sender.LoggedinUser);
}
else if (method == PacketBuilder.SECCODE_AWARD)
{
byte[] ExpectedSecCode = sender.LoggedinUser.GenerateSecCode();
byte[] GotSecCode = new byte[4];
Array.ConstrainedCopy(packet, 2, GotSecCode, 0, GotSecCode.Length);
Logger.DebugPrint(sender.LoggedinUser.Username + " Sent sec code: " + BitConverter.ToString(GotSecCode).Replace("-", " "));
if (ExpectedSecCode.SequenceEqual(GotSecCode))
{
if (packet.Length < 6)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent a seccode AWARD request with invalid size");
return;
}
string packetStr = Encoding.UTF8.GetString(packet);
string awardIdStr = packetStr.Substring(6, packetStr.Length - 6 - 2);
int value = -1;
try
{
value = int.Parse(awardIdStr);
}
catch (FormatException)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent correct sec code, but invalid awardid value");
return;
}
sender.LoggedinUser.Awards.AddAward(Award.GetAwardById(value));
return;
}
else
{
byte[] errorMessage = PacketBuilder.CreateChat(Messages.InvalidSecCodeError, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(errorMessage);
Logger.HackerPrint(sender.LoggedinUser.Username + " Sent invalid sec code");
return;
}
}
else if (method == PacketBuilder.SECCODE_SCORE || method == PacketBuilder.SECCODE_TIME)
{
bool time = (method == PacketBuilder.SECCODE_TIME);
@ -329,10 +372,10 @@ namespace HISP.Server
string packetStr = Encoding.UTF8.GetString(packet);
string gameInfoStr = packetStr.Substring(6, packetStr.Length - 6 - 2);
if(gameInfoStr.Contains("|"))
if (gameInfoStr.Contains("|"))
{
string[] gameInfo = gameInfoStr.Split('|');
if(gameInfo.Length < 2)
if (gameInfo.Length < 2)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent a invalid seccode score request");
return;
@ -340,7 +383,7 @@ namespace HISP.Server
string gameTitle = gameInfo[0];
string gameScoreStr = gameInfo[1];
int value = -1;
try
{
@ -378,7 +421,7 @@ namespace HISP.Server
Logger.HackerPrint(sender.LoggedinUser.Username + " Sent invalid sec code");
return;
}
}
}
else if (method == PacketBuilder.SECCODE_MONEY)
{
@ -533,7 +576,7 @@ namespace HISP.Server
return;
}
}
else if(method == PacketBuilder.PLAYERINFO_HIGHSCORES_LIST)
else if (method == PacketBuilder.PLAYERINFO_HIGHSCORES_LIST)
{
string packetStr = Encoding.UTF8.GetString(packet);
string gameName = packetStr.Substring(2, packetStr.Length - 4);

View file

@ -46,7 +46,7 @@ namespace HISP.Server
public const byte SECCODE_SCORE = 0x3D;
public const byte SECCODE_TIME = 0x3E;
public const byte SECCODE_MONEY = 0x1E;
public const byte SECCODE_AWARD = 0x33;
public const byte NPC_START_CHAT = 0x14;
public const byte NPC_CONTINUE_CHAT = 0x15;
@ -550,9 +550,9 @@ namespace HISP.Server
public static byte[] CreatePlayerData(int money, int playerCount, int mail)
{
byte[] moneyStrBytes = Encoding.UTF8.GetBytes(money.ToString());
byte[] playerStrBytes = Encoding.UTF8.GetBytes(playerCount.ToString());
byte[] mailStrBytes = Encoding.UTF8.GetBytes(mail.ToString());
byte[] moneyStrBytes = Encoding.UTF8.GetBytes(money.ToString("N0"));
byte[] playerStrBytes = Encoding.UTF8.GetBytes(playerCount.ToString("N0"));
byte[] mailStrBytes = Encoding.UTF8.GetBytes(mail.ToString("N0"));
MemoryStream ms = new MemoryStream();
ms.WriteByte(PACKET_BASE_STATS);