Skip to content

Commit

Permalink
[OneBot] Implemented LocationSegment.cs.cs
Browse files Browse the repository at this point in the history
  • Loading branch information
Linwenxuan authored and Linwenxuan committed Feb 11, 2024
1 parent facf661 commit c3538ff
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 9 deletions.
44 changes: 44 additions & 0 deletions Lagrange.OneBot/Core/Entity/Common/LightApp.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Text.Json.Serialization;

namespace Lagrange.OneBot.Core.Entity.Common;
#pragma warning disable CS8618

[Serializable]
public class LightApp
{
[JsonPropertyName("app")] public string App { get; set; }

[JsonPropertyName("config")] public Config Config { get; set; }

[JsonPropertyName("desc")] public string Desc { get; set; }

[JsonPropertyName("from")] public long From { get; set; }

[JsonPropertyName("meta")] public Meta Meta { get; set; }

[JsonPropertyName("prompt")] public string Prompt { get; set; }

[JsonPropertyName("ver")] public string Ver { get; set; }

[JsonPropertyName("view")] public string View { get; set; }
}

[Serializable]
public class Config
{
[JsonPropertyName("autosize")] public bool Autosize { get; set; }

[JsonPropertyName("ctime")] public long Ctime { get; set; }

[JsonPropertyName("forward")] public bool Forward { get; set; }

[JsonPropertyName("token")] public string Token { get; set; }

[JsonPropertyName("type")] public string Type { get; set; }
}

[Serializable]
public class Meta
{
[JsonPropertyName("Location.Search")] public LocationSearch LocationSearch { get; set; }
}
22 changes: 22 additions & 0 deletions Lagrange.OneBot/Core/Entity/Common/LocationSearch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Text.Json.Serialization;

namespace Lagrange.OneBot.Core.Entity.Common;
#pragma warning disable CS8618

[Serializable]
public class LocationSearch
{
[JsonPropertyName("address")] public string Address { get; set; }

[JsonPropertyName("enum_relation_type")] public long EnumRelationType { get; set; }

[JsonPropertyName("from")] public string From { get; set; }

[JsonPropertyName("id")] public string Id { get; set; }

[JsonPropertyName("lat")] public string Lat { get; set; }

[JsonPropertyName("lng")] public string Lng { get; set; }

[JsonPropertyName("name")] public string Name { get; set; }
}
81 changes: 81 additions & 0 deletions Lagrange.OneBot/Core/Message/Entity/LocationSegment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Lagrange.Core.Message;
using Lagrange.Core.Message.Entity;
using Lagrange.OneBot.Core.Entity.Common;

namespace Lagrange.OneBot.Core.Message.Entity;

[Serializable]
public partial class LocationSegment(float latitude, float longitude)
{
public LocationSegment() : this(0f, 0f) { }

[JsonPropertyName("lat")] [CQProperty] public float Latitude { get; set; } = latitude;

[JsonPropertyName("lon")] [CQProperty] public float Longitude { get; set; } = longitude;

[JsonPropertyName("title")] public string Title { get; set; } = string.Empty;

[JsonPropertyName("content")] public string Content { get; set; } = string.Empty;
}

[SegmentSubscriber(typeof(LightAppEntity), "location")]
public partial class LocationSegment : SegmentBase
{
public override void Build(MessageBuilder builder, SegmentBase segment)
{
if (segment is not LocationSegment location) return;

var json = new LightApp
{
App = "com.tencent.map",
Config = new Config
{
Autosize = false,
Ctime = DateTimeOffset.UtcNow.Second,
Forward = true,
Token = "626399d3453d0693fe19e12cd3747c56",
Type = "normal"
},
Desc = "",
From = 1,
Meta = new Meta
{
LocationSearch = new LocationSearch
{
EnumRelationType = 1,
From = "plusPanel",
Id = "",
Lat = location.Latitude.ToString("F5"),
Lng = location.Longitude.ToString("F5"),
Name = location.Title,
Address = location.Content
}
},
Prompt = $"[Location]{location.Content}",
Ver = "1.1.2.21",
View = "LocationShare"
};

builder.LightApp(JsonSerializer.Serialize(json));
}

public override SegmentBase? FromEntity(MessageChain chain, IMessageEntity entity)
{
if (entity is not LightAppEntity lightApp) throw new ArgumentException("Invalid entity type.");

if (JsonSerializer.Deserialize<LightApp>(lightApp.Payload) is { App: "com.tencent.map" } app)
{
return new LocationSegment
{
Latitude = float.Parse(app.Meta.LocationSearch.Lat),
Longitude = float.Parse(app.Meta.LocationSearch.Lng),
Content = app.Meta.LocationSearch.Address,
Title = app.Meta.LocationSearch.Name,
};
}

return null;
}
}
22 changes: 14 additions & 8 deletions Lagrange.OneBot/Core/Message/MessageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ public sealed class MessageService
private readonly LagrangeWebSvcCollection _service;
private readonly LiteDatabase _context;
private readonly IConfiguration _config;
private readonly Dictionary<Type, (string Type, SegmentBase Factory)> _entityToSegment;
private readonly Dictionary<Type, List<(string Type, SegmentBase Factory)>> _entityToFactory;

private static readonly IJsonTypeInfoResolver Resolver;
private static readonly JsonSerializerOptions Options;


static MessageService()
{
Resolver = new DefaultJsonTypeInfoResolver { Modifiers = { ModifyTypeInfo } };
Options = new JsonSerializerOptions { TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { ModifyTypeInfo } } };
}

public MessageService(BotContext bot, LagrangeWebSvcCollection service, LiteDatabase context, IConfiguration config)
Expand All @@ -45,15 +46,17 @@ public MessageService(BotContext bot, LagrangeWebSvcCollection service, LiteData
invoker.OnGroupMessageReceived += OnGroupMessageReceived;
invoker.OnTempMessageReceived += OnTempMessageReceived;

_entityToSegment = new Dictionary<Type, (string, SegmentBase)>();
_entityToFactory = new Dictionary<Type, List<(string, SegmentBase)>>();
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
var attribute = type.GetCustomAttribute<SegmentSubscriberAttribute>();
if (attribute != null)
{
var instance = (SegmentBase)type.CreateInstance(false);
instance.Database = _context;
_entityToSegment[attribute.Entity] = (attribute.Type, instance);

if (_entityToFactory.TryGetValue(attribute.Entity, out var factories)) factories.Add((attribute.Type, instance));
else _entityToFactory[attribute.Entity] = [(attribute.Type, instance)];
}
}
}
Expand Down Expand Up @@ -105,9 +108,12 @@ public List<OneBotSegment> Convert(MessageChain chain)

foreach (var entity in chain)
{
if (_entityToSegment.TryGetValue(entity.GetType(), out var instance))
if (_entityToFactory.TryGetValue(entity.GetType(), out var instances))
{
result.Add(new OneBotSegment(instance.Type, instance.Factory.FromEntity(chain, entity)));
foreach (var instance in instances)
{
if (instance.Factory.FromEntity(chain, entity) is { } segment) result.Add(new OneBotSegment(instance.Type, segment));
}
}
}

Expand All @@ -134,7 +140,7 @@ private static string ToRawMessage(List<OneBotSegment> segments)
{
rawMessageBuilder.Append("[CQ:");
rawMessageBuilder.Append(segment.Type);
foreach (var property in JsonSerializer.SerializeToElement(segment.Data, new JsonSerializerOptions { TypeInfoResolver = Resolver }).EnumerateObject())
foreach (var property in JsonSerializer.SerializeToElement(segment.Data, Options).EnumerateObject())
{
rawMessageBuilder.Append(',');
rawMessageBuilder.Append(property.Name);
Expand Down
2 changes: 1 addition & 1 deletion Lagrange.OneBot/Core/Message/SegmentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ public abstract class SegmentBase

public abstract void Build(MessageBuilder builder, SegmentBase segment);

public abstract SegmentBase FromEntity(MessageChain chain, IMessageEntity entity);
public abstract SegmentBase? FromEntity(MessageChain chain, IMessageEntity entity);
}

0 comments on commit c3538ff

Please sign in to comment.