[Plugin] SampSharp - Write gamemodes in .NET
#41

Target framework should be 4.0 or can be 4.5?
Reply
#42

Quote:
Originally Posted by PaSaSaP
Посмотреть сообщение
Target framework should be 4.0 or can be 4.5?
Must be 4.5, since SA-MP# is build using 4.5
Reply
#43

I actually like this...

But I have some questions... Does this affect the speed of execution in runtime or does it affect any thing ?
And will I have to create a wrapper for each and every plugin I use ?
Reply
#44

Quote:
Originally Posted by Ahmad45123
Посмотреть сообщение
I actually like this...

But I have some questions... Does this affect the speed of execution in runtime or does it affect any thing ?
And will I have to create a wrapper for each and every plugin I use ?
I haven't been able to do a very accurate benchmark test. But as far as I know (and if you program you gamemode efficiently) it is faster than pawn and a slower than c++(sampgdk).

It's not my intention to create a wrapper for every plugin myself. I've made it very easy to create a wrapper yourself on purpose.
However, if there is a very useful plugin and I have some spare time I might give it a shot if you tell me which plugins you are talking about. (no promises!)
Reply
#45

How connect to MySQL? Can I use MySQL/R33 or get another library, for example like here?

And second question: How to create subclass of GtaVehicle?
Код:
    class Vehicle: GtaVehicle
    {
        public Vehicle(int i): base(i)
        {

        }
    }
or maybe:
Код:
class Vehicle
{
    GtaVehicle vehicle;
    //for example in constructor
    public Vehicle(GtaVehicle v)
    {
        vehicle = v;
    }
}
Another: Is it possible to write filterscripts with C#?

If I has:
Код:
    class Vehicle: GtaVehicle
    {
        public Vehicle(int v):base(v)
        {

        }
    }
And this:
Код:
        [Command("car")]
        public static void commandCar(Player player)
        {
            player.SendClientMessage("No i masz samochуd.");

            //Vehicle car = new Vehicle(GtaVehicle.CreateStatic(400, player.Position, 0.0f, 1, 2));
            //car.vehicle.Position = player.Position;
            //player.PutInVehicle(car.vehicle);

            Vehicle car = (Vehicle) Vehicle.Create(400, player.Position, player.Rotation.Z, 3, 3, -1);
            car.Position = player.Position;
            player.PutInVehicle((GtaVehicle) car);
        }
I has exception:
Код:
[06/03/2015 20:15:36] Exception thrownOnPlayerCommandText:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidCastException: Cannot cast from source type to destination type.
  at PaSaSaPGM.GameMode.commandCar (PaSaSaPGM.World.Player player) [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at SampSharp.GameMode.SAMP.Commands.DetectedCommand.RunCommand (SampSharp.GameMode.World.GtaPlayer player, System.String args) [0x00000] in <filename unknown>:0 
  at SampSharp.GameMode.Controllers.CommandController+<>c__DisplayClass8.<gameMode_PlayerCommandText>b__6 (System.Tuple`2 candidate) [0x00000] in <filename unknown>:0 
  at System.Linq.Enumerable.First[Tuple`2] (IEnumerable`1 source, System.Func`2 predicate, Fallback fallback) [0x00000] in <filename unknown>:0 
  at System.Linq.Enumerable.FirstOrDefault[Tuple`2] (IEnumerable`1 source, System.Func`2 predicate) [0x00000] in <filename unknown>:0 
  at SampSharp.GameMode.Controllers.CommandController.gameMode_PlayerCommandText (System.Object sender, SampSharp.GameMode.Events.CommandTextEventArgs e) [0x00000] in <filename unknown>:0 
  at (wrapper delegate-invoke) System.EventHandler`1<SampSharp.GameMode.Events.CommandTextEventArgs>:invoke_void_object_TEventArgs (object,SampSharp.GameMode.Events.CommandTextEventArgs)
  at SampSharp.GameMode.BaseMode.OnPlayerCommandText (SampSharp.GameMode.World.GtaPlayer player, SampSharp.GameMode.Events.CommandTextEventArgs e) [0x00000] in <filename unknown>:0 
  at PaSaSaPGM.GameMode.OnPlayerCommandText (SampSharp.GameMode.World.GtaPlayer player, SampSharp.GameMode.Events.CommandTextEventArgs e) [0x00000] in <filename unknown>:0 
  at SampSharp.GameMode.BaseMode.OnPlayerCommandText (Int32 playerid, System.String cmdtext) [0x00000] in <filename unknown>:0
But if I use GtaVehicle instead my Vehicle, it works. I know, that I do casting and it is source of that exception, but I want know how to create vehicles in my own class, which is subclass of GtaVehicle, no field.
Reply
#46

@PaSaSaP:

About inheriting from SA-MP# classes:
It works like this:
In SA-MP# there is a register with types to use when initializing objects for specific handles(e.g. vehicles)

When an event gets called with a vehicleid, it will, by default, initialize a GtaVehicle instance (if not was made with the specified handle earlier) and use that as a vehicle. If you want to create your own vehicle class, you need to tell SA-MP# to use that type instead. Here's how:

Create your Vehicle class:
Код:
public class Vehicle: GtaVehicle
{
    public Vehicle(int id) : base(id)
    {
    }
}
Create a VehicleController class, in which you tell SA-MP# to use your Vehicle class:
Код:
    public class VehicleController : GtaVehicleController
    {
        public override void RegisterTypes()
        {
            Vehicle.Register<Vehicle>();
        }
    }
Register the controller to SA-MP#; In your gamemode class:
Код:
        protected override void LoadControllers(ControllerCollection controllers)
        {
            base.LoadControllers(controllers);

            controllers.Remove<GtaVehicleController>();
            controllers.Add(new VehicleController());
        }
It works the same for player classes, object classes and so on.


About mysql, personally, I use NHibernate. Its a very nice ORM system. An example can be found here:
https://github.com/ikkentim/SampShar...NHibernateTest
Reply
#47

What about CallRemoteFunction() and similar functions?
Reply
#48

Quote:
Originally Posted by PaSaSaP
Посмотреть сообщение
What about CallRemoteFunction() and similar functions?
Since SA-MP# is designed to create sandalone game modes (not dependent / using filterscripts) CallRemoteFunction is not supplied by default.

You can use Native.CallNative to call it if you want.

Код:
Native.CallNative("CallRemoteFunction", __arglist("Function", arg1, arg2));
Reply
#49

I am so stupid to understand how to use this. I got the error:
Код:
[07/03/2015 20:34:06] Exception thrownOnGameModeInit:
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

 ---> NHibernate.HibernateException: Could not create the driver from NHibernate.Driver.MySqlDataDriver, NHibernate, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Configuration.ConfigurationErrorsException: Failed to find or load the registered .Net Framework Data Provider 'MySql.Data.MySqlClient'.
  at System.Data.Common.DbProviderFactories.GetFactory (System.String providerInvariantName) [0x00000] in <filename unknown>:0 
  at NHibernate.Driver.ReflectionBasedDriver..ctor (System.String providerInvariantName, System.String driverAssemblyName, System.String connectionTypeName, System.String commandTypeName) [0x00000] in <filename unknown>:0 
  at NHibernate.Driver.MySqlDataDriver..ctor () [0x00000] in <filename unknown>:0 
  at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0 
  at NHibernate.Bytecode.ActivatorObjectsFactory.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0 
  at NHibernate.Connection.ConnectionProvider.ConfigureDriver (IDictionary`2 settings) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at NHibernate.Connection.ConnectionProvider.ConfigureDriver (IDictionary`2 settings) [0x00000] in <filename unknown>:0 
  at NHibernate.Connection.ConnectionProvider.Configure (IDictionary`2 settings) [0x00000] in <filename unknown>:0 
  at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider (IDictionary`2 settings) [0x00000] in <filename unknown>:0 
  at NHibernate.Cfg.SettingsFactory.BuildSettings (IDictionary`2 properties) [0x00000] in <filename unknown>:0 
  at NHibernate.Cfg.Configuration.BuildSettings () [0x00000] in <filename unknown>:0 
  at NHibernate.Cfg.Configuration.BuildSessionFactory () [0x00000] in <filename unknown>:0 
  at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory () [0x00000] in <filename unknown>:0 
  at PaSaSaPGM.DbSession.CreateSessionFactory () [0x00000] in <filename unknown>:0 
  at PaSaSaPGM.DbSession.get_Factory () [0x00000] in <filename unknown>:0 
  at PaSaSaPGM.DbSession.OpenSession () [0x00000] in <filename unknown>:0 
  at PaSaSaPGM.GameMode.OnInitialized (System.EventArgs e) [0x00000] in <filename unknown>:0 
  at SampSharp.GameMode.BaseMode.OnGameModeInit () [0x00000] in <filename unknown>:0
In OnInitialized I has:
Код:
//Lets store our current session
            using (ISession session = DbSession.OpenSession())
            {
                session.Save(new ServerInfo { Number = new Random().Next(0, 100) });
            }

            //...

            //... lets open a bunch of sessions
            
            for (int x = 0; x < 10; x++)
            {
                using (ISession session = DbSession.OpenSession())
                {
                    //Get first 10 sessions
                    IQueryable<ServerInfo> serverinfos = session.Query<ServerInfo>().Take(10);

                    foreach (ServerInfo si in serverinfos)
                    {
                        Console.WriteLine(si);
                    }
                }
            }
And others from test GM. MySQL is correct.
Reply
#50

@PaSaSaP
Quote:

Failed to find or load the registered .Net Framework Data Provider 'MySql.Data.MySqlClient'

Are you using the redistributed mono from the readme or the mono from the mono website?
Reply
#51

I changed MySQL package ;'D

I have the Vehicle class and it looks like You wrote above. What is difference between constructors:

Код:
new Vehicle(400);
new Vehicle(400, new Vector(1.0f, 1.0f, 1.0f), 1.0f, 3, 3);
If I use first, there is no car in server, but if I use second, the vehicle is created in the server.
Reply
#52

Quote:
Originally Posted by PaSaSaP
Посмотреть сообщение
I changed MySQL package ;'D

I have the Vehicle class and it looks like You wrote above. What is difference between constructors:

Код:
new Vehicle(400);
new Vehicle(400, new Vector(1.0f, 1.0f, 1.0f), 1.0f, 3, 3);
If I use first, there is no car in server, but if I use second, the vehicle is created in the server.
I don't know. You tell me, you created those constructors. GtaVehicle only has one constructor, and that's with a vehicleid (id! not model) GtaVehicle also has a couple of static functions to spawn vehicles: Create and CreateStatic:
http://sampsharp.timpotze.nl/html/fd...a1d1ac754d.htm
Reply
#53

Is it possible to create server with Your plugin to linux server? Or it can be only windows server?
Reply
#54

Quote:
Originally Posted by PaSaSaP
Посмотреть сообщение
Is it possible to create server with Your plugin to linux server? Or it can be only windows server?
First sentance:

Quote:
Originally Posted by OP
SA-MP# works both on Linux and Windows
Reply
#55

OK. I cant find how to start with linux server. Mybe I am so stupid to do this. So how to start with linux server?
Reply
#56

Quote:
Originally Posted by PaSaSaP
Посмотреть сообщение
OK. I cant find how to start with linux server. Mybe I am so stupid to do this. So how to start with linux server?
I haven't compiled the plugin for version 0.4.1 on linux yet. You'll have to do so yourself. Here are some basic instructions: https://github.com/ikkentim/SampShar...ing-the-plugin
Reply
#57

On hosting mono was installed and I has the same problem. I changed to release build and info is like before:
Код:
Failed (plugins/libtest.so: undefined symbol: mono_string_to_utf8)
I run server on debian with compiled by me library, it is the same problem.

___

Problem solved. While compilation the addictional flag is required: -lrt added to end of gcc/g++ line.
Reply
#58

Been doing some testing with this. Some additional questions:

How to handle dialogs inline, such as implementing the response logic in the relevant classes?

I tried spawning the player manually using this.spawn() in the Player class when the login would be successful. In Pawn, i used to return 0 on OnPlayerRequestClass. What would be the preffered way in Sharp, since the manual spawn does not work.
Reply
#59

Quote:
Originally Posted by Sithis
Посмотреть сообщение
Been doing some testing with this. Some additional questions:

How to handle dialogs inline, such as implementing the response logic in the relevant classes?

I tried spawning the player manually using this.spawn() in the Player class when the login would be successful. In Pawn, i used to return 0 on OnPlayerRequestClass. What would be the preffered way in Sharp, since the manual spawn does not work.

Код:
var dialog = new Dialog(...);
dialog.Response += (sender, args) {
    // handle response
};
------

For the other question,
Set PreventSpawning to true
https://github.com/ikkentim/SampShar...entArgs.cs#L43

https://github.com/ikkentim/SampShar...Player.cs#L585
Reply
#60

Awesome. This is a great way to create complex scripts. You obviously know what you're doing and you pay attention to people that want to become better at scripting in C#.

You deserve a cookie!
Reply


Forum Jump:


Users browsing this thread: 9 Guest(s)