Skip to content

Commit

Permalink
[Simantics, Server] Substantial Backend Improvements
Browse files Browse the repository at this point in the history
- Fix a bug where the game could crash when switching properties.
- Global Tuning: Tuning that is sent as soon as the player logs in, and
is available in city view.
- Tuning Presets: Tuning that can be applied as part of an ingame timed
event. This can include tuning for motives, object payouts, skill speed
and more - and allows all of these things to be automatically changed
while the server is running.
- Admin API for Events. (should make things easier on other M.O.M.I. ;)
)
- Tuning changes while the server is running now immediately update any
lots that are open. (fixes dynamic payouts not updating til a lot
restart)
- Interpolation for slot-slot movement. Very simple right now - could be
improved for things like table slots.
- Hidden objects (like the go here destination) no longer update
shadows, causing a stutter.
- New collision test function - should be helpful finding the desyncs
that have been hitting popular lots.
- Fix object shadows when shadows for surrounding lots are enabled
- Terrain Force logic now uses global tuning.
- "Community" category flag can now be set by Volcanic.
  • Loading branch information
riperiperi committed Jun 22, 2019
1 parent ec31134 commit 6cefa61
Show file tree
Hide file tree
Showing 63 changed files with 827 additions and 50 deletions.
13 changes: 13 additions & 0 deletions TSOClient/FSO.IDE/ResourceBrowser/OBJDEditor.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions TSOClient/FSO.IDE/ResourceBrowser/OBJDEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public void Init(GameObject obj, ObjectWindow master)
{ CatGames, new PropFlagCombo("LotCategories", 8) },
{ CatEntertainment, new PropFlagCombo("LotCategories", 9) },
{ CatResidence, new PropFlagCombo("LotCategories", 10) },
{ CatCommunity, new PropFlagCombo("LotCategories", 11) },
{ SklCooking, new PropFlagCombo("RatingSkillFlags", 0) },
{ SklMechanical, new PropFlagCombo("RatingSkillFlags", 1) },
{ SklLogic, new PropFlagCombo("RatingSkillFlags", 2) },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using FSO.Server.Api.Core.Models;
using FSO.Server.Api.Core.Utils;
using FSO.Server.Database.DA.DbEvents;
using FSO.Server.Database.DA.Tuning;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace FSO.Server.Api.Core.Controllers.Admin
{
[EnableCors("AdminAppPolicy")]
[Route("admin/events")]
[ApiController]
public class AdminEventsController : ControllerBase
{
//List events
[HttpGet]
public IActionResult Get(int limit, int offset, string order)
{
if (limit == 0) limit = 20;
if (order == null) order = "start_day";
var api = Api.INSTANCE;
api.DemandModerator(Request);
using (var da = api.DAFactory.Get())
{

if (limit > 100)
{
limit = 100;
}

var result = da.Events.All((int)offset, (int)limit, order);
return ApiResponse.PagedList<DbEvent>(Request, HttpStatusCode.OK, result);
}
}

[HttpGet("presets")]
public IActionResult GetPresets()
{
var api = Api.INSTANCE;
api.DemandModerator(Request);
using (var da = api.DAFactory.Get())
{
return new JsonResult(da.Tuning.GetAllPresets().ToList());
}
}

[HttpPost("presets")]
public IActionResult CreatePreset([FromBody]PresetCreateModel request)
{
var api = Api.INSTANCE;
api.DemandModerator(Request);
using (var da = api.DAFactory.Get())
{
//make the preset first
var preset_id = da.Tuning.CreatePreset(
new DbTuningPreset()
{
name = request.name,
description = request.description,
flags = request.flags
});

foreach (var item in request.items)
{
da.Tuning.CreatePresetItem(new DbTuningPresetItem()
{
preset_id = preset_id,
tuning_type = item.tuning_type,
tuning_table = item.tuning_table,
tuning_index = item.tuning_index,
value = item.value
});
}
return new JsonResult(da.Tuning.GetAllPresets().ToList());
}
}

[HttpGet("presets/{preset_id}")]
public IActionResult GetPresetEntries(int preset_id)
{
var api = Api.INSTANCE;
api.DemandModerator(Request);
using (var da = api.DAFactory.Get())
{
return new JsonResult(da.Tuning.GetPresetItems(preset_id).ToList());
}
}

[HttpDelete("presets/{preset_id}")]
public IActionResult DeletePreset(int preset_id)
{
var api = Api.INSTANCE;
api.DemandModerator(Request);
using (var da = api.DAFactory.Get())
{
return da.Tuning.DeletePreset(preset_id) ? (IActionResult)Ok() : NotFound();
}
}

// POST admin/updates (start update generation)
[HttpPost]
public IActionResult Post([FromBody]EventCreateModel request)
{
var api = Api.INSTANCE;
api.DemandModerator(Request);

using (var da = api.DAFactory.Get())
{
DbEventType type;
try
{
type = Enum.Parse<DbEventType>(request.type);
}
catch
{
return BadRequest("Event type must be one of:" + string.Join(", ", Enum.GetNames(typeof(DbEventType))));
}
var model = new DbEvent()
{
title = request.title,
description = request.description,
start_day = request.start_day,
end_day = request.end_day,
type = type,
value = request.value,
value2 = request.value2,
mail_subject = request.mail_subject,
mail_message = request.mail_message,
mail_sender = request.mail_sender,
mail_sender_name = request.mail_sender_name
};
return new JsonResult(new { id = da.Events.Add(model) });
}
}

[HttpDelete]
[Route("{id}")]
public IActionResult Delete(int id)
{
var api = Api.INSTANCE;
api.DemandModerator(Request);

using (var da = api.DAFactory.Get())
{
if (!da.Events.Delete(id)) return NotFound();
}

return Ok();
}

}
}
38 changes: 38 additions & 0 deletions TSOClient/FSO.Server.Api.Core/Models/EventCreateModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FSO.Server.Api.Core.Models
{
public class EventCreateModel
{
public string title;
public string description;
public DateTime start_day;
public DateTime end_day;
public string type;
public int value;
public int value2;
public string mail_subject;
public string mail_message;
public int mail_sender;
public string mail_sender_name;
}

public class PresetCreateModel
{
public string name;
public string description;
public int flags;
public List<PresetItemModel> items;
}

public class PresetItemModel
{
public string tuning_type;
public int tuning_table;
public int tuning_index;
public float value;
}
}
12 changes: 10 additions & 2 deletions TSOClient/FSO.Server.Api.Core/Services/GithubUpdateUploader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,16 @@ public async Task<string> UploadFile(string destPath, string fileName, string gr
}

using (var file = File.Open(fileName, System.IO.FileMode.Open, FileAccess.Read, FileShare.Read)) {
var asset = await client.Repository.Release.UploadAsset(release, new ReleaseAssetUpload(destPath, "application/zip", file, new TimeSpan(1, 0, 0)));
return asset.BrowserDownloadUrl;
try
{
var asset = await client.Repository.Release.UploadAsset(release, new ReleaseAssetUpload(destPath, "application/zip", file, null));
return asset.BrowserDownloadUrl;
} catch (Exception e)
{
//last time i tried, it mysteriously failed here but the file was uploaded :thinking:
Console.WriteLine($"!! Upload request for {destPath} failed, check it actually succeeded !! \n" + e.ToString());
return $"https://github.com/{Config.User}/{Config.Repository}/releases/download/{groupName}/{destPath}";
}
}
}
}
Expand Down
54 changes: 50 additions & 4 deletions TSOClient/FSO.Server.Clients/AriesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,40 @@ public interface IAriesEventSubscriber
void InputClosed(AriesClient session);
}

public class NullIOHandler : IoHandler
{
public void ExceptionCaught(IoSession session, Exception cause)
{
}

public void InputClosed(IoSession session)
{
}

public void MessageReceived(IoSession session, object message)
{
}

public void MessageSent(IoSession session, object message)
{
}

public void SessionClosed(IoSession session)
{
}

public void SessionCreated(IoSession session)
{
}

public void SessionIdle(IoSession session, IdleStatus status)
{
}

public void SessionOpened(IoSession session)
{
}
}

public class AriesClient : IoHandler
{
Expand Down Expand Up @@ -98,11 +131,15 @@ public void Connect(IPEndPoint target)
{
if (Connector != null)
{
//dispose our old connector, if one is present.
Connector.Dispose();
Disconnect();
//old connector might still be establishing connection...
//we need to stop that
Connector.Handler = new NullIOHandler(); //don't hmu
//we can't cancel a mina.net connector, but we can sure as hell ~~avenge it~~ stop it from firing events.
//if we tried to dispose it, we'd get random disposed object exceptions because mina doesn't expect you to cancel that early.
Disconnect(); //if we have already established a connection, make sure it is closed.
}
Connector = new AsyncSocketConnector();
var connector = Connector;
Connector.ConnectTimeoutInMillis = 10000;
//Connector.FilterChain.AddLast("logging", new LoggingFilter());

Expand All @@ -112,7 +149,16 @@ public void Connect(IPEndPoint target)
//Connector.FilterChain.AddFirst("ssl", ssl);

Connector.FilterChain.AddLast("protocol", new ProtocolCodecFilter(new AriesProtocol(Kernel)));
var future = Connector.Connect(target, new Action<IoSession, IConnectFuture>(OnConnect));
var future = Connector.Connect(target, (IoSession session, IConnectFuture future2) =>
{
if (future2.Canceled || future2.Exception != null)
{
if (connector.Handler != null) SessionClosed(session);
}

if (connector.Handler is NullIOHandler) session.Close(true);
else this.Session = session;
});

Task.Run(() =>
{
Expand Down
6 changes: 6 additions & 0 deletions TSOClient/FSO.Server.Database/DA/DbEvents/DbEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public class DbEvent
public string mail_message { get; set; }
public int? mail_sender { get; set; }
public string mail_sender_name { get; set; }

public string type_str {
get {
return type.ToString();
}
}
}

public class DbEventParticipation
Expand Down
4 changes: 3 additions & 1 deletion TSOClient/FSO.Server.Database/DA/DbEvents/IEvents.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using FSO.Server.Database.DA.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
Expand All @@ -8,6 +9,7 @@ namespace FSO.Server.Database.DA.DbEvents
{
public interface IEvents
{
PagedList<DbEvent> All(int offset = 0, int limit = 20, string orderBy = "start_day");
List<DbEvent> GetActive(DateTime time);
int Add(DbEvent evt);
bool Delete(int event_id);
Expand Down
Loading

0 comments on commit 6cefa61

Please sign in to comment.