Giter Club home page Giter Club logo

openmod's Introduction

OpenMod Discord

OpenMod is a plugin framework for .NET.

It supports authorization, plugin configurations, internalization, command handling and much more. OpenMod can be used for games, bot frameworks, web servers or anything else and has official implementations for Unturned, Rust (WIP) and a standalone console.

For a list of available plugins, visit openmod-plugins.

Features

OpenMod is based on modern C# code and best practices.

  • Modern API for plugin development with C# and Unity best practices
  • Plugin installation with NuGet
  • Can self update with NuGet
  • Based on .NET Generic Host
  • IoC and Dependency Injection using Autofac
  • Configure OpenMod and plugins with yaml configurations, environment variables, commandline arguments, etc.
  • Serilog for logging, including rich configuration options via logging.yml

Getting Started

To get started, visit the OpenMod Documentation.

If you would like to install OpenMod, installation guides for the following platforms are available:

If you want to make plugins for OpenMod, you can get started by reading the Making your first plugin page.

Supported Games

Currently Unturned is the only supported game. More games might follow in the future. OpenMod can work side-by-side with RocketMod.

License

See LICENSE file for more information.

Build Status

Framework

OpenMod.API OpenMod.Bootstrapper OpenMod.NuGet OpenMod.Core OpenMod.Runtime OpenMod.Analyzers OpenMod.Templates OpenMod.EntityFrameworkCore

Extensions

OpenMod.Extensions.Games.Abstractions OpenMod.Extensions.Economy.Abstractions

Standalone

OpenMod.Standalone

UnityEngine

OpenMod.UnityEngine.Redist OpenMod.UniTask OpenMod.UnityEngine

Unturned

OpenMod.Unturned.Redist OpenMod.Unturned OpenMod.Unturned.Module

Rust

OpenMod.Rust.Redist OpenMod.Rust OpenMod.Rust.Oxide.Redist OpenMod.Rust.Oxide OpenMod.Rust.Oxide.Extension OpenMod.Rust.Oxide.PermissionLink

Code of Conduct

This project uses the .NET Foundation Code of Conduct.

.NET Foundation

This project is supported by the .NET Foundation.

openmod's People

Contributors

archie426 avatar arechii avatar aviadmini avatar bermingen avatar bios9 avatar charterino avatar corbyncc avatar cyberandrii avatar dependabot[bot] avatar diffoz avatar eiromplays avatar fahrettinenes avatar iamsilk avatar johnanater avatar k1nd0 avatar kotyk7 avatar kr4ken-9 avatar nathandontgotdis avatar negrifelipe avatar pandetthe avatar papershredder432 avatar paradox304 avatar pustalorc avatar riku8405 avatar rube200 avatar senior-s avatar sunnamed434 avatar the-sluggiest-cat avatar trojaner avatar xandercodes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openmod's Issues

CommandBase permission

private readonly string m_CommandPermission;
Should be protected instead.

So the commands can know what your permission is.
Example:
if (!await m_PermissionChecker.CheckPermissionAsync(Context.Actor, $"{m_CommandPermission}.can_do_to_other_player")) { //no permission }

Unnecessary files

From what I see the releases of the unturned module contains the unturned and unity assemblies, so I think it would be better if they are not contained in the zip and probably check if there is already a lib on unturned side.

Server blocked

Some times when OpenMod.Unturned starts or gets reload it freeze the serve (console stop responding, didn't test as player)
Captura de Ecrã (55)
(each blank line was a command that disappeared)

Testing on Linux

Before releasing, we need to test if OpenMod for Unturned works on Linux.

Basic Events

  • On shutdown event
  • Permission Group changes event
  • Plugin load event
  • Plugin unload event
  • User first connect event
  • User chat event

Investigate proxying OpenMod permissions to RocketMod

Proposal:
We could add support for proxying OpenMod permissions to RocketMod. This could be done by patching related functions here.

Pro:

  • Users do not have to maintain two separate permission files.

Contra:

  • Migrating from RocketMod to OpenMod will become harder.
    Possible solution: Implementing proxying via a RocketMod 4 or OpenMod plugin. This way users can choose if they want to proxy the permissions or not. Might also be possible to make a migrator plugin that imports RocketMod permissions.

Questions:
-> What will happen to RocketMod permissions plugins? Will this break any plugins?
-> Should RocketMod be kept completely separated from OpenMod? What features should be proxied?

IUserDataStore changes

IUserDataStore should have a new method:

async Task<UserData> GetUserDataAsync(string userId, string userNameOrId);
or
 async Task<UserData> GetOnlineUserDataAsync(string userId, string userNameOrId);

This makes it possible for plugins to get a player's data by name, so some plugins can be universal instead of just for a specific game

(I can do a pr if u want)
(and I just found out that I can access the data directly, but this should still be implemented)

Custom assembly services

When openmod loads the plugin, it should detect if there is any class with a specific attribute and add to its containerBuilder.
Example: Database class

Events not working

I have this code:

public sealed class Plugin: OpenModPluginBase, IEventListener<UserConnectedEvent>
{
    //...
    public Task HandleEventAsync(object _, UserConnectedEvent userConnectedEvent)
    {
        //..
    }
}

but the event is not being called.

(i haven't tested the other events)

On Join Pending exceptions

When player connects to unturned server:

[2020-06-19 22:24:40 ERR][SDG.Unturned] Object reference not set to an instance of an object
[2020-06-19 22:24:40 ERR][SDG.Unturned]   at OpenMod.Core.Users.UserDataStore+<GetUsersDataAsync>d__6.MoveNext () [0x00021] in <5f3d3891ed0740ca95d82bfbd1689bd7>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at OpenMod.Core.Users.UserDataStore+<GetUserDataAsync>d__3.MoveNext () [0x0009c] in <5f3d3891ed0740ca95d82bfbd1689bd7>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at OpenMod.Core.Users.UserDataSeeder+<SeedUserDataAsync>d__3.MoveNext () [0x00092] in <5f3d3891ed0740ca95d82bfbd1689bd7>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at OpenMod.Unturned.Users.UnturnedUserProvider+<>c__DisplayClass12_0+<<OnPendingPlayerConnected>b__0>d.MoveNext () [0x000ea] in <8e82413027394fd99428eaad84b81eef>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException (System.Threading.Tasks.Task task) [0x00015] in <e609703832c1447ba57019bc973cc564>:0 
  at Nito.AsyncEx.AsyncContext+<>c__DisplayClass15_0.<Run>b__0 (System.Threading.Tasks.Task t) [0x0000b] in <15f79df01f394725ba0a0a0856096654>:0 
  at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke () [0x00024] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Threading.Tasks.Task.Execute () [0x00010] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) [0x0003e] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) [0x00028] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) [0x00008] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at System.Runtime.CompilerServices.TaskAwaiter.GetResult () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0 
  at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException (System.Threading.Tasks.Task task) [0x00015] in <e609703832c1447ba57019bc973cc564>:0 
  at Nito.AsyncEx.AsyncContext.Run (System.Func`1[TResult] action) [0x0006c] in <15f79df01f394725ba0a0a0856096654>:0 
  at OpenMod.Core.Helpers.AsyncHelper.RunSync (System.Func`1[TResult] action) [0x00000] in <5f3d3891ed0740ca95d82bfbd1689bd7>:0 
  at OpenMod.Unturned.Users.UnturnedUserProvider.OnPendingPlayerConnected (Steamworks.ValidateAuthTicketResponse_t callback, System.Boolean& isValid, System.String& explanation) [0x00029] in <8e82413027394fd99428eaad84b81eef>:0 
  at SDG.Unturned.Provider.handleValidateAuthTicketResponse (Steamworks.ValidateAuthTicketResponse_t callback) [0x000b5] in <583092d77ee44d62b65636564269a567>:0 

An exception also happens when the player connects to the server and when it disconnects, but I think it is related to the first one I showed

CommandContextBuilder not checking Priority

private ICommandRegistration GetCommandRegistration(ICommandActor actor, string name, IEnumerable<ICommandRegistration> commandRegistrations)
{
var baseQuery = commandRegistrations.Where(d => d.SupportsActor(actor));
// todo: could be done in a single iteration
// ReSharper disable PossibleMultipleEnumeration
return baseQuery.FirstOrDefault(d => d.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
?? baseQuery.FirstOrDefault(d => d.Aliases != null && d.Aliases.Any(e => e.Equals(name, StringComparison.OrdinalIgnoreCase)));
// ReSharper restore PossibleMultipleEnumeration
}

Add openmod.commands.yaml

Configure command names, aliases, etc. (planned after release)

Format:

- id: OpenMod.Commands.OpenModCommands.CommandOpenMod
  name: openmod
  aliases: [ "om" ]
  priority: Highest # can be one of "Highest, High, Normal, Low, Lowest"
  data: { } # can be used by plugins
  enabled: true
- id: OpenMod.Commands.OpenModCommands.CommandOpenModInstall
  parentId: OpenMod.Commands.OpenModCommands.CommandOpenMod
  name: openmod
  aliases: [ "i", "+" ]
  priority: Highest
  data: { }
  enabled: true

Libs and NuGet Parallel Download

Some libs like Harmony and Json are included on release file, they should be downloaded by nuget.
And talking about downloading stuff with nuget,
To speed up the time, transfers could be made in parallel (if possible)
ps: I tried to do it but they were duplicated

OpenMod.Extenions.Games.Abstractions

OpenMod itself is engine- and game agnostic, so it has no concept of players, entities, etc. Platforms which are not games (for example, a Discord bot framework or the standalone console) do not support these.

The OpenMod.Extenions.Games.Abstractions package will provide related abstractions. Platforms which support the game related features can implement these interfaces, services and events.

  • IPlayer [inherits from IUser]
    • bool HasHealth { get; }
    • float Health { get; set; }
    • float MaxHealth { get; set; }
  • IPlayerManager (similar to IUserManager, but only works with online players)
  • PlayerDeathEvent
  • PlayerRespawnEvent
  • ???

OpenMod.Games will be only supported by Unturned for now.

Plugin directory

[18:07:50 ERR] Failed to load plugin from type: OpenMod.Uconomy.Uconomy in assembly: OpenMod.Uconomy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
System.IO.DirectoryNotFoundException: C:\Unturned_Server\Servers\Test_Rm4\OpenMod\plugins\UconomyPlugin\
  at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor (System.String root, Microsoft.Extensions.FileProviders.Physical.ExclusionFilters filters) [0x0004f] in <c7d9afd87883477cad5e6b28df563148>:0
  at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor (System.String root) [0x00000] in <c7d9afd87883477cad5e6b28df563148>:0
  at Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath (Microsoft.Extensions.Configuration.IConfigurationBuilder builder, System.String basePath) [0x0001c] in <cbe20bd126324ec4893e5252aad320f9>:0
  at OpenMod.Core.Plugins.PluginActivator+<>c__DisplayClass10_0.<TryActivatePluginAsync>b__0 (Autofac.ContainerBuilder containerBuilder) [0x00034] in <1c1096c632fe46cd9453039d0e393efe>:0
  at Autofac.Core.Lifetime.LifetimeScope.CreateScopeRestrictedRegistry (System.Object tag, System.Action`1[T] configurationAction) [0x000ad] in <0e43922c38cb4505ab27fe9ce1207b2d>:0
  at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope (System.Object tag, System.Action`1[T] configurationAction) [0x0001b] in <0e43922c38cb4505ab27fe9ce1207b2d>:0
  at Autofac.Core.Lifetime.LifetimeScope.BeginLifetimeScope (System.Action`1[T] configurationAction) [0x00007] in <0e43922c38cb4505ab27fe9ce1207b2d>:0
  at OpenMod.Core.Plugins.PluginActivator+<TryActivatePluginAsync>d__10.MoveNext () [0x000fa] in <1c1096c632fe46cd9453039d0e393efe>:0

Minor NuGetPackageManager rework

  • Pass NuGetPackageManager instance from DynamicBoostrapper to Runtime, use same instance for NuGetPluginSource
  • Add IgnoredPackages list, include OpenMod.Unturned.Redist, OpenMod.UnityEngine.Redist and OpenMod.NuGet

OpenMod.Unturned.Module includes wrong Project References

OpenMod.Unturned.Module wrongfully includes OpenMod.API, Core, Runtime and other dlls. These must be bootstrapped via NuGet. Might create a separate module for debugging and removing project references completely to avoid this issue.

Unknown Types on missing Libs

When a plugin uses an external lib such as Mysql.Dat, the method ScanAssemblyForCommmmands returns an exception,
on line foreach (var type in assembly.GetLoadableTypes()).

The value of assembly.GetLoadableTypes() is not null but as soon as it enters the loop (without anything else) it automatically returns an exception (ReflectionTypeLoadException);

if we catch that exception, we can still get all types of that assembly.

System.Reflection.ReflectionTypeLoadException: Exception of type 'System.Reflection.ReflectionTypeLoadException' was thrown.
  at (wrapper managed-to-native) System.Reflection.Assembly.GetTypes(System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () [0x00000] in <e1319b7195c343e79b385cd3aa43f5dc>:0
  at System.Reflection.Assembly+<get_DefinedTypes>d__150.MoveNext () [0x0001e] in <e1319b7195c343e79b385cd3aa43f5dc>:0
  at System.Linq.Enumerable+SelectEnumerableIterator`2[TSource,TResult].MoveNext () [0x00029] in <fbb5ed17eb6e46c680000f8910ebb50c>:0
  at OpenMod.Core.Commands.OpenModComponentCommandSource.ScanAssemblyForCommmmands (System.Reflection.Assembly assembly) [0x000bf] in <e2ef437a02db443aa69fb68957a0e2ed>:0
  at OpenMod.Core.Commands.OpenModComponentCommandSource..ctor (Microsoft.Extensions.Logging.ILogger logger, OpenMod.API.IOpenModComponent openModComponent, System.Reflection.Assembly assembly) [0x0001f] in <e2ef437a02db443aa69fb68957a0e2ed>:0
  at OpenMod.Core.Commands.OpenModComponentCommandSource..ctor (Microsoft.Extensions.Logging.ILogger logger, OpenMod.API.IOpenModComponent openModComponent) [0x0000e] in <e2ef437a02db443aa69fb68957a0e2ed>:0
  at OpenMod.Core.Plugins.OpenModPluginBase.LoadAsync () [0x00044] in <e2ef437a02db443aa69fb68957a0e2ed>:0
  at OpenMod.Core.Plugins.OpenModUniversalPlugin.LoadAsync () [0x00000] in <e2ef437a02db443aa69fb68957a0e2ed>:0
  at OpenMod.Core.Plugins.PluginActivator+<TryActivatePluginAsync>d__10.MoveNext () [0x00182] in <e2ef437a02db443aa69fb68957a0e2ed>:0

Deploying a fix on this PullRequest: #49
(Tested)

Unturned Commands

Default unturned commands do not appear to be working correctly.
Captura de Ecrã (57)
The one that seems to "work" shows '1 1 1' in the chat with green color

Update yamls with new values

When translations and plugin configs get updated with new values they will not get applied to existing configs. Need to parse and compare the yaml included with the assembly to the one on the disk and add missing values. Merges could be done here: https://github.com/openmod/OpenMod/blob/master/framework/OpenMod.Core/Helpers/AssemblyHelper.cs#L10.

Note: the solution for this must work on nested values (e.g. adding the missing aaa.bbb.ccc if aaa.bbb exists) and it must not delete comments.

Unturned Console Input Bug

When writing or pressing backspace, it clears the upper line. Probably related to overriding Unturned's input handling here and here. Needs investigation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.