add simple jumping arena and advanced jumping arena,

This commit is contained in:
SilicaAndPina 2021-02-18 02:31:21 +13:00
parent 934a737613
commit 8f0ed68110
10 changed files with 859 additions and 78 deletions

View file

@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using HISP.Player;
@ -20,7 +19,6 @@ namespace HISP.Server
private Thread recvPackets;
private Timer updateTimer;
private Timer inactivityTimer;
private Timer warnTimer;
@ -29,7 +27,6 @@ namespace HISP.Server
private bool isDisconnecting = false;
private int keepAliveInterval = 60 * 1000;
private int updateInterval = 60 * 1000;
private int totalMinutesElapsed = 0;
private int oneMinute = 60 * 1000;
@ -57,24 +54,19 @@ namespace HISP.Server
}
// unsure of actural timings, would be more or less impossible to know
// without the original source code :(
// From testing hunger seemed to go down fastest, then thirst, and finally tiredness.
foreach(HorseInstance horse in LoggedinUser.HorseInventory.HorseList)
{
if (totalMinutesElapsed % 2 == 0)
{
horse.BasicStats.Thirst--;
horse.BasicStats.Hunger--;
if (horse.BasicStats.Thirst <= 0)
horse.BasicStats.Health -= 5;
}
if (totalMinutesElapsed % 2 == 0 && (horse.BasicStats.Thirst <= 100 || horse.BasicStats.Thirst <= 100 || horse.BasicStats.Tiredness <= 100))
horse.BasicStats.Health--;
if (totalMinutesElapsed % 60 == 0)
{
horse.BasicStats.Mood--;
horse.BasicStats.Shoes--;
horse.BasicStats.Tiredness--;
}
@ -83,11 +75,12 @@ namespace HISP.Server
}
if (totalMinutesElapsed % 1 == 0)
if (totalMinutesElapsed % 2 == 0)
{
LoggedinUser.Thirst--;
if (totalMinutesElapsed % 5 == 0)
LoggedinUser.Hunger--;
}
if (totalMinutesElapsed % 10 == 0)
LoggedinUser.Tiredness--;
@ -120,11 +113,7 @@ namespace HISP.Server
{
Kick(Messages.FormatIdleKickMessage());
}
private void updateTimerTick(object state)
{
GameServer.UpdateWorld(this);
GameServer.UpdatePlayer(this);
}
public void Login(int id)
{
// Check for duplicate
@ -141,7 +130,6 @@ namespace HISP.Server
Database.SetIpAddress(id, RemoteIp);
updateTimer = new Timer(new TimerCallback(updateTimerTick), null, updateInterval, updateInterval);
inactivityTimer = new Timer(new TimerCallback(keepAliveTimerTick), null, keepAliveInterval, keepAliveInterval);
}
private bool receivePackets()
@ -193,8 +181,6 @@ namespace HISP.Server
// Stop Timers
if (updateTimer != null)
updateTimer.Dispose();
if(inactivityTimer != null)
inactivityTimer.Dispose();
if(warnTimer != null)
@ -290,6 +276,9 @@ namespace HISP.Server
case PacketBuilder.PACKET_ITEM_INTERACTION:
GameServer.OnItemInteraction(this,Packet);
break;
case PacketBuilder.PACKET_ARENA_SCORE:
GameServer.OnArenaScored(this, Packet);
break;
case PacketBuilder.PACKET_QUIT:
GameServer.OnQuitPacket(this, Packet);
break;

View file

@ -723,6 +723,19 @@ namespace HISP.Server
Trainer.Trainers.Add(trainer);
Logger.DebugPrint("Registered Training Pen: " + trainer.Id + " for " + trainer.ImprovesStat);
}
int totalArenas = gameData.arena.Count;
for(int i = 0; i < totalArenas; i++)
{
int arenaId = gameData.arena[i].arena_id;
string arenaType = gameData.arena[i].arena_type;
int arenaEntryCost = gameData.arena[i].entry_cost;
int raceEvery = gameData.arena[i].race_every;
int slots = gameData.arena[i].slots;
int timeout = gameData.arena[i].timeout;
Arena arena = new Arena(arenaId, arenaType, arenaEntryCost, raceEvery, slots, timeout);
Logger.DebugPrint("Registered Arena: " + arena.Id.ToString()+" as " + arena.Type);
}
HorseInfo.HorseNames = gameData.horses.names.ToObject<string[]>();
@ -746,6 +759,50 @@ namespace HISP.Server
Map.ModIsleX = gameData.messages.commands.mod_isle.x;
Map.ModIsleY = gameData.messages.commands.mod_isle.y;
// Hammock Text
Messages.HammockText = gameData.messages.meta.hammock;
// Competitions
Messages.ArenaResultsMessage = gameData.messages.meta.arena.results;
Messages.ArenaPlacingFormat = gameData.messages.meta.arena.placing;
Messages.ArenaAlreadyEntered = gameData.messages.meta.arena.already_entered;
Messages.ArenaFirstPlace = gameData.messages.meta.arena.first_place;
Messages.ArenaSecondPlace = gameData.messages.meta.arena.second_place;
Messages.ArenaThirdPlace = gameData.messages.meta.arena.thirst_place;
Messages.ArenaFourthPlace = gameData.messages.meta.arena.fourth_place;
Messages.ArenaFifthPlace = gameData.messages.meta.arena.fifth_place;
Messages.ArenaSixthPlace = gameData.messages.meta.arena.sixth_place;
Messages.ArenaEnteredInto = gameData.messages.meta.arena.enter_into;
Messages.ArenaCantAfford = gameData.messages.meta.arena.cant_afford;
Messages.ArenaYourScoreFormat = gameData.messages.meta.arena.your_score;
Messages.ArenaJumpingStartup = gameData.messages.meta.arena.jumping_start_up;
Messages.ArenaDraftStartup = gameData.messages.meta.arena.draft_start_up;
Messages.ArenaRacingStartup = gameData.messages.meta.arena.racing_start_up;
Messages.ArenaConformationStartup = gameData.messages.meta.arena.conformation_start_up;
Messages.ArenaYouWinFormat = gameData.messages.meta.arena.winner;
Messages.ArenaOnlyWinnerWins = gameData.messages.meta.arena.only_winner_wins;
Messages.ArenaTooHungry = gameData.messages.meta.arena.too_hungry;
Messages.ArenaTooThirsty = gameData.messages.meta.arena.too_thisty;
Messages.ArenaNeedsFarrier = gameData.messages.meta.arena.farrier;
Messages.ArenaTooTired = gameData.messages.meta.arena.too_tired;
Messages.ArenaNeedsVet = gameData.messages.meta.arena.needs_vet;
Messages.ArenaEventNameFormat = gameData.messages.meta.arena.event_name;
Messages.ArenaCurrentlyTakingEntriesFormat = gameData.messages.meta.arena.currently_taking_entries;
Messages.ArenaCompetitionInProgress = gameData.messages.meta.arena.competition_in_progress;
Messages.ArenaYouHaveHorseEntered = gameData.messages.meta.arena.horse_entered;
Messages.ArenaCompetitionFull = gameData.messages.meta.arena.competiton_full;
Messages.ArenaEnterHorseFormat = gameData.messages.meta.arena.enter_horse;
Messages.ArenaCurrentCompetitors = gameData.messages.meta.arena.current_competitors;
Messages.ArenaCompetingHorseFormat = gameData.messages.meta.arena.competing_horses;
// Horse Games
Messages.HorseGamesSelectHorse = gameData.messages.meta.horse_games.select_a_horse;
Messages.HorseGamesHorseEntryFormat = gameData.messages.meta.horse_games.horse_entry;

View file

@ -40,17 +40,46 @@ namespace HISP.Server
/*
* Private stuff
*/
private static int gameTickSpeed = 4320; // Changing this to ANYTHING else will cause desync with the client.
private static int gameTickSpeed = 480; // Changing this to ANYTHING else will cause desync with the client.
private static int totalMinutesElapsed = 0;
private static int oneMinute = 1000 * 60;
private static List<GameClient> connectedClients = new List<GameClient>();
private static Timer gameTimer; // Controls in-game time.
private static Timer minuteTimer; // ticks every real world minute.
private static int lastServerTime = 0;
private static void onGameTick(object state)
{
World.TickWorldClock();
Database.DecHorseTrainTimeout();
gameTimer.Change(gameTickSpeed, gameTickSpeed);
if(World.ServerTime.Minutes != lastServerTime)
{
Arena.StartArenas(World.ServerTime.Minutes);
Database.DecHorseTrainTimeout();
// write time to database:
Database.SetServerTime(World.ServerTime.Minutes, World.ServerTime.Days, World.ServerTime.Years);
// Ranch Windmill Payments
if (World.ServerTime.Minutes % 720 == 0) // every 12 hours
{
Logger.DebugPrint("Paying windmill owners . . . ");
foreach (Ranch ranch in Ranch.Ranches)
{
int ranchOwner = ranch.OwnerId;
if (ranchOwner != -1)
{
int moneyToAdd = 5000 * ranch.GetBuildingCount(8); // Windmill
if (GameServer.IsUserOnline(ranchOwner))
GameServer.GetUserById(ranchOwner).Money += moneyToAdd;
else
Database.SetPlayerMoney(Database.GetPlayerMoney(ranchOwner) + moneyToAdd, ranchOwner);
}
}
}
gameTimer.Change(gameTickSpeed, gameTickSpeed);
lastServerTime = World.ServerTime.Minutes;
}
}
private static void onMinuteTick(object state)
{
@ -89,15 +118,20 @@ namespace HISP.Server
Update(client);
byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(client.LoggedinUser.Money, GameServer.GetNumberOfPlayers(), client.LoggedinUser.MailBox.UnreadMailCount);
client.SendPacket(BaseStatsPacketData);
UpdateWorld(client);
UpdatePlayer(client);
}
Database.IncPlayerTirednessForOfflineUsers();
if(totalMinutesElapsed % 60 == 0)
{
foreach (HorseInstance horse in Database.GetMostSpoiledHorses())
{
horse.BasicStats.Tiredness = 1000;
horse.BasicStats.Health = 1000;
horse.BasicStats.Mood = 1000;
horse.BasicStats.Hunger = 1000;
horse.BasicStats.Thirst = 1000;
}
@ -756,7 +790,7 @@ namespace HISP.Server
break;
}
trainHorseInst.BasicStats.Experience += trainer.ExperienceGained;
trainHorseInst.TrainTimer = trainer.ImprovesAmount + trainer.ExperienceGained * 50;
trainHorseInst.TrainTimer = 1440;
byte[] trainSuccessfulMessage = PacketBuilder.CreateChat(Messages.FormatTrainedInStatFormat(trainHorseInst.Name, trainer.ImprovesStat), PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(trainSuccessfulMessage);
@ -893,6 +927,95 @@ namespace HISP.Server
Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to feed a non existant item to a horse.");
break;
}
case PacketBuilder.HORSE_ENTER_ARENA:
randomId = 0;
packetStr = Encoding.UTF8.GetString(packet);
randomIdStr = packetStr.Substring(2, packetStr.Length - 4);
try
{
randomId = int.Parse(randomIdStr);
}
catch (Exception)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid randomid to horse interaction packet ");
break;
}
if (sender.LoggedinUser.HorseInventory.HorseIdExist(randomId))
{
HorseInstance horseInstance = sender.LoggedinUser.HorseInventory.GetHorseById(randomId);
World.SpecialTile tile = World.GetSpecialTile(sender.LoggedinUser.X, sender.LoggedinUser.Y);
if (tile.Code.StartsWith("ARENA-"))
{
string[] arenaInfo = tile.Code.Split('-');
int arenaId = int.Parse(arenaInfo[1]);
Arena arena = Arena.GetAreaById(arenaId);
if(!Arena.UserHasEnteredHorseInAnyArena(sender.LoggedinUser))
{
if(horseInstance.BasicStats.Thirst <= 300)
{
byte[] tooThirsty = PacketBuilder.CreateChat(Messages.ArenaTooThirsty, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(tooThirsty);
break;
}
else if (horseInstance.BasicStats.Hunger <= 300)
{
byte[] tooHungry = PacketBuilder.CreateChat(Messages.ArenaTooHungry, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(tooHungry);
break;
}
else if (horseInstance.BasicStats.Shoes <= 300)
{
byte[] needsFarrier = PacketBuilder.CreateChat(Messages.ArenaNeedsFarrier, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(needsFarrier);
break;
}
else if (horseInstance.BasicStats.Tiredness <= 300)
{
byte[] tooTired = PacketBuilder.CreateChat(Messages.ArenaTooTired, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(tooTired);
break;
}
else if (horseInstance.BasicStats.Health <= 300)
{
byte[] needsVet = PacketBuilder.CreateChat(Messages.ArenaNeedsVet, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(needsVet);
break;
}
if (sender.LoggedinUser.Money >= arena.EntryCost)
{
arena.AddEntry(sender.LoggedinUser, horseInstance);
sender.LoggedinUser.Money -= arena.EntryCost;
byte[] enteredIntoCompetition = PacketBuilder.CreateChat(Messages.ArenaEnteredInto, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(enteredIntoCompetition);
UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y, true);
break;
}
else
{
byte[] cantAffordEntryFee = PacketBuilder.CreateChat(Messages.ArenaCantAfford, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(cantAffordEntryFee);
break;
}
}
else
{
byte[] allreadyEntered = PacketBuilder.CreateChat(Messages.ArenaAlreadyEntered, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(allreadyEntered);
}
}
}
else
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to enter a non existant horse into a competition.");
break;
}
break;
case PacketBuilder.HORSE_RELEASE:
randomId = 0;
packetStr = Encoding.UTF8.GetString(packet);
@ -2336,6 +2459,43 @@ namespace HISP.Server
break;
}
}
public static void OnArenaScored(GameClient sender, byte[] packet)
{
if (!sender.LoggedIn)
{
Logger.ErrorPrint(sender.RemoteIp + " Requested user information when not logged in.");
return;
}
if(packet.Length <= 3)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + "Sent invalid Arena Scored Packet.");
return;
}
string packetStr = Encoding.UTF8.GetString(packet);
string scoreStr = packetStr.Substring(1, packet.Length - 3);
int score = -1;
try
{
score = int.Parse(scoreStr);
}
catch(FormatException)
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Scored NAN in an arena.");
return;
}
if(Arena.UserHasEnteredHorseInAnyArena(sender.LoggedinUser))
{
Arena enteredArena = Arena.GetArenaUserEnteredIn(sender.LoggedinUser);
enteredArena.SubmitScore(sender.LoggedinUser, score);
}
else
{
Logger.ErrorPrint(sender.LoggedinUser.Username + " Scored in an arena while not in one");
}
return;
}
public static void OnUserInfoRequest(GameClient sender, byte[] packet)
{
if (!sender.LoggedIn)
@ -2984,16 +3144,33 @@ namespace HISP.Server
sender.SendPacket(bestScoreBeaten);
sender.LoggedinUser.Money += 2500;
}
else if (newHighscore && !time)
else if (newHighscore)
{
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatHighscoreBeatenMessage(value), PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
}
else
{
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatTimeBeatenMessage(value), PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
if(time)
{
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatTimeBeatenMessage(value), PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
}
else
{
byte[] chatPacket = PacketBuilder.CreateChat(Messages.FormatHighscoreBeatenMessage(value), PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(chatPacket);
}
}
if(sender.LoggedinUser.Highscores.HighscoreList.Length >= 30)
sender.LoggedinUser.Awards.AddAward(Award.GetAwardById(12)); // Minigame Player
if (sender.LoggedinUser.Highscores.HighscoreList.Length >= 60)
sender.LoggedinUser.Awards.AddAward(Award.GetAwardById(13)); // Minigame Master
if (Database.GetPlayerTotalMinigamesPlayed(sender.LoggedinUser.Id) >= 1000)
sender.LoggedinUser.Awards.AddAward(Award.GetAwardById(14)); // Minigame Nut
if (Database.GetPlayerTotalMinigamesPlayed(sender.LoggedinUser.Id) >= 10000)
sender.LoggedinUser.Awards.AddAward(Award.GetAwardById(15)); // Minigame Crazy
}
else
{
@ -5377,12 +5554,19 @@ namespace HISP.Server
public static void OnDisconnect(GameClient sender)
{
connectedClients.Remove(sender);
if (sender.LoggedIn)
{
Database.SetPlayerLastLogin(Convert.ToInt32(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds()), sender.LoggedinUser.Id); // Set last login date
Database.RemoveOnlineUser(sender.LoggedinUser.Id);
// Delete Arena Entries
if(Arena.UserHasEnteredHorseInAnyArena(sender.LoggedinUser))
{
Arena arena = Arena.GetArenaUserEnteredIn(sender.LoggedinUser);
arena.DeleteEntry(sender.LoggedinUser);
}
// Send disconnect message
byte[] logoutMessageBytes = PacketBuilder.CreateChat(Messages.FormatLogoutMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT);
foreach (GameClient client in ConnectedClients)
@ -5397,6 +5581,7 @@ namespace HISP.Server
if (client.LoggedinUser.Id != sender.LoggedinUser.Id)
client.SendPacket(playerRemovePacket);
}
connectedClients.Remove(sender);
}
@ -5404,7 +5589,7 @@ namespace HISP.Server
* Get(Some Information)
*/
public static bool IsUserOnline(int id)
{
try
@ -5950,6 +6135,17 @@ namespace HISP.Server
}
}
}
if(mapCode == "HAMMOCK")
{
byte[] hammockText = PacketBuilder.CreateChat(Messages.HammockText, PacketBuilder.CHAT_BOTTOM_RIGHT);
forClient.SendPacket(hammockText);
forClient.LoggedinUser.Tiredness = 1000;
foreach(HorseInstance horse in forClient.LoggedinUser.HorseInventory.HorseList)
{
horse.BasicStats.Tiredness = 1000;
}
}
return true;
}
public static void StartServer()

View file

@ -37,6 +37,7 @@ namespace HISP.Server
public const byte PACKET_KEEP_ALIVE = 0x7C;
public const byte PACKET_DYNAMIC_BUTTON = 0x45;
public const byte PACKET_DYNAMIC_INPUT = 0x46;
public const byte PACKET_ARENA_SCORE = 0x2D;
public const byte PACKET_PLAYER = 0x18;
public const byte PACKET_INVENTORY = 0x17;
public const byte PACKET_TRANSPORT = 0x29;
@ -62,6 +63,7 @@ namespace HISP.Server
public const byte HORSE_LIST = 0x0A;
public const byte HORSE_LOOK = 0x14;
public const byte HORSE_FEED = 0x15;
public const byte HORSE_ENTER_ARENA = 0x2D;
public const byte HORSE_PET = 0x18;
public const byte HORSE_PROFILE = 0x2C;
public const byte HORSE_PROFILE_EDIT = 0x14;