scutgame / scut Goto Github PK
View Code? Open in Web Editor NEWScut is a free, open source, stable game server framework, which support C#/Python/Lua script, and support Unity3d, Cocos2dx, FlashAir client access.
Scut is a free, open source, stable game server framework, which support C#/Python/Lua script, and support Unity3d, Cocos2dx, FlashAir client access.
系统为centos 6.5 按照教程之中的介绍,安装好mono等环节,redis已装,httpd服务为apache,服务都已开启。
输入mono GameServer.exe之后报错:
Missing method .ctor in assembly /data/tmp/scut/Console/ZyGames.Framework.Game.dll, type System.Runtime.CompilerServices.DynamicAttribute
Can't find custom attr constructor image: /data/tmp/scut/Console/ZyGames.Framework.Game.dll mtoken: 0x0a000003
Stacktrace:
at <0xffffffff>
at ZyGames.Framework.Game.Runtime.ConsoleRuntimeHost.Start () <0x0003a>
at GameServer.Program.Main (string[]) <0x0003c>
at (wrapper runtime-invoke) .runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>
Native stacktrace:
mono() [0x4a3645]
/lib64/libpthread.so.0(+0xf710) [0x7f87fada0710]
/lib64/libc.so.6(gsignal+0x35) [0x7f87faa2f925]
/lib64/libc.so.6(abort+0x175) [0x7f87faa31105]
mono() [0x62d9fd]
mono() [0x62daa7]
mono() [0x515700]
mono(mono_class_get_full+0xe0) [0x5148b0]
mono(mono_field_from_token+0x2bc) [0x53c93c]
mono() [0x45c4c3]
mono() [0x41b32f]
mono() [0x41cfa3]
mono() [0x41dabb]
mono() [0x4a7aa8]
mono() [0x4a84c4]
[0x409d8de6]
Debug info from gdb:
Aborted
I find this Scut framework and really like it. So Scut is ready in production ? and who is maintain this project
version 6.7.9.10
it will not work. because it doesn't have model script..
ScriptEngines.cs
private static ScriptRuntimeScope InitScriptRuntimeScope()
{
//star compile
if (Interlocked.Exchange(ref _isCompiling, 1) == 0)
{
ScriptRuntimeDomain runtimeDomain = null;
try
{
string runtimePath = MathUtils.RuntimePath ?? MathUtils.RuntimeBinPath;
AppDomain.CurrentDomain.AppendPrivatePath(ScriptCompiler.ScriptPath);
runtimeDomain = new ScriptRuntimeDomain(typeof(ScriptRuntimeDomain).Name, new[] { _settupInfo.RuntimePrivateBinPath, ScriptCompiler.ScriptPath });
foreach (var assemblyName in _settupInfo.ReferencedAssemblyNames)
{
//排除System的dll
if (string.IsNullOrEmpty(assemblyName) ||
!Path.IsPathRooted(assemblyName)) continue;
string key = Path.GetFileNameWithoutExtension(assemblyName);
runtimeDomain.LoadAssembly(key, assemblyName);
}
var scope = runtimeDomain.CreateScope(_settupInfo);
// FAILED HERE BECAUSE IT DOES NOT HAVE MODEL SCRIPT
if (scope == null || scope.ModelAssembly == null) return scope;
bool isFirstRun = _runtimeDomain == null;
if (!isFirstRun && _settupInfo.ModelChangedBefore != null)
{
_settupInfo.ModelChangedBefore(_runtimeDomain.Scope.ModelAssembly);
}
runtimeDomain.MainInstance = runtimeDomain.Scope.Execute(_settupInfo.ScriptMainProgram, _settupInfo.ScriptMainTypeName) as IMainScript;
// NEVER COME HERE
_runtimeDomain = runtimeDomain;
Remark the IF statement or Add Dummy entity in Model folder
Hi!
This is awesome game server so far! Could you please add example or LUA api for mobile to connect to scut server? So game developer using quick-x, cocos2dx-lua, corona sdk can use that api to build game.
Thanks so much!
Python3出来好多年了啊,能更新下支持python3最好了
With TCP mode
Test with ZyTest tool configured 100 thread and 100 runtimes
SocketListener.cs IO_Completed method have ObjectDisposedException.
Reason: GameSession manage session and it delete socket that is waiting process
p.s you can reproduce this easily by change timeout parameter and interval OnSessionClear method
with Heavyload environment
Server seems to be stuck occasionally
Reason: Send CloseHandshake message to already disposed socket
ContractTools/release/Web.config配置文件中,
connectionString="server=localhost;database=ContractDB;uid=root;pwd=123456"
server=192.168.x.xxx, 协议平台打开的界面下拉框都是空白的, 数据库已经导入, 并且配置的数据库连接串账号与密码都是正确的.
System.Web.Compilation.ParseException
The parent type 'ContractTools.WebApp.Default' does not derive from System.Web.UI.Page
Description: Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Details: The parent type 'ContractTools.WebApp.Default' does not derive from System.Web.UI.Page
Error origin: Parser
Error source file: /var/www/contracttools/Default.aspx
Exception stack trace:
at System.Web.UI.BaseParser.ThrowParseException (System.String message, System.Object[] parms) <0x41715ee0 + 0x00087> in :0
at System.Web.UI.TemplateParser.SetBaseType (System.String type) <0x416a0da0 + 0x001eb> in :0
at System.Web.UI.TemplateParser.ProcessMainAttributes (IDictionary atts) <0x416ac790 + 0x00bc3> in :0
at System.Web.UI.TemplateControlParser.ProcessMainAttributes (IDictionary atts) <0x416ab590 + 0x0042f> in :0
at System.Web.UI.PageParser.ProcessMainAttributes (IDictionary atts) <0x416a8000 + 0x027ef> in :0
at System.Web.UI.TemplateParser.AddDirective (System.String directive, IDictionary atts) <0x416a6b80 + 0x0019e> in :0
at System.Web.UI.TemplateControlParser.AddDirective (System.String directive, IDictionary atts) <0x416a65d0 + 0x0054b> in :0
at System.Web.UI.PageParser.AddDirective (System.String directive, IDictionary atts) <0x416a6130 + 0x0042b> in :0
at System.Web.Compilation.AspGenerator.GetInheritedType (System.String fileContents, System.String filename) <0x416a3520 + 0x00401> in :0
at System.Web.Compilation.AspGenerator.GetRootBuilderType (System.IO.Stream inputStream, System.String filename) <0x416a2cf0 + 0x000bf> in :0
at System.Web.Compilation.AspGenerator.CreateRootBuilder (System.IO.Stream inputStream, System.String filename) <0x416a2b00 + 0x0003b> in :0
at System.Web.Compilation.AspGenerator.InitParser (System.IO.TextReader reader, System.String filename) <0x416a1f90 + 0x00353> in :0
at System.Web.Compilation.AspGenerator.Parse (System.IO.TextReader reader, System.String filename, Boolean doInitParser) <0x416a1b80 + 0x00063> in :0
at System.Web.Compilation.GenericBuildProvider1[TParser].Parse () <0x4169b730 + 0x000c3> in <filename unknown>:0 at System.Web.Compilation.GenericBuildProvider
1[TParser].GenerateCode () <0x4169b660 + 0x00016> in :0
at System.Web.Compilation.GenericBuildProvider`1[TParser].GenerateCode (System.Web.Compilation.AssemblyBuilder assemblyBuilder) <0x4169b420 + 0x0004c> in :0
at System.Web.Compilation.BuildManager.GenerateAssembly (System.Web.Compilation.AssemblyBuilder abuilder, System.Web.Compilation.BuildProviderGroup group, System.Web.VirtualPath vp, Boolean debug) <0x4169a840 + 0x002e2> in :0
Error source context:
Error lines: 1, 1
1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ContractTools.WebApp.Default" ValidateRequest="false" %>
2:
3:
when one server send heart package to another server, another server can not refresh the session ,
becase the code at GameSocketHost can not decode the package.
Change the RemoteService.cs at line 229.
add the code after line 228, heatParam["MsgId"] = 0; can solve the problem
if you call reload function on PersonalCacheStruct especially entity has ReadWriteDB property
it will re-load data from Database.
and it set value by ReadEntityProperty method in SqlDataReceiver.cs
it call entity's Property function and it fire event NotifyChange event and the value will be added to SyncQueueManager. clearly not expected behavior.
moreover the "ReadEntityProperty" function set value sequencely
each set value fire event and the "not completed setting entity' will be added;
in another word.
if you have some entity like below
[EntityTable]
class someentity
{
[EntityField(true)]
public long userID {get;set}
[EntityField(true)]
public long subkey {get;set}
}
and we have one data from database as below
UserID, subKey
1, 2
now call
PersonalCacheStruct().Reload();
then we will have two DataSyncQueue item
1-0, 1-2
we don't need add this data to DataSyncQueue again. just waste performance
官网打不开,三年未更新了!Scut已死?哎,国人都是三分钟热度!我说观察先,结果给观察死了!
Change code like this
public static dynamic GetPersonalEntity(string redisKey, out CacheItemSet itemSet) { itemSet = null; dynamic entity = null; KeyValuePair<string, CacheItemSet> itemPair; if (TryGetContainerCacheItem(redisKey, out itemPair)) { itemSet = itemPair.Value; if (itemSet != null) { switch (itemPair.Value.ItemType) { case CacheType.Entity: entity = itemPair.Value.ItemData; break; case CacheType.Dictionary: var set = itemPair.Value.ItemData as BaseCollection; if (set != null) { set.TryGetValue(itemPair.Key, out entity); } break; default: TraceLog.WriteError("Not suported CacheType:{0} for GetPersonalEntity key:{1}", itemPair.Value.ItemType, redisKey); break; } } } if (entity == null) { //while is remove entity is empty. //TraceLog.WriteComplement("GetPersonalEntity key:{0} is empty.", redisKey); } return entity; }
`public static bool TryGetContainerCacheItem(string redisKey, out KeyValuePair<string, CacheItemSet> itemPair, int periodTime = 0)
{
itemPair = default(KeyValuePair<string, CacheItemSet>);
CacheItemSet cacheItem;
string[] keys = (redisKey ?? "").Split('_');
if (keys.Length == 2 && !string.IsNullOrEmpty(keys[0]))
{
CacheContainer container = null;
string typeName = RedisConnectionPool.DecodeTypeName(keys[0]);
var schema = EntitySchemaSet.Get(typeName);
periodTime = periodTime > 0 ? periodTime : schema.PeriodTime;
if (_writePools != null && !_writePools.TryGetValue(typeName, out container))
{
_writePools.InitContainer(typeName);
_writePools.TryGetValue(typeName, out container);
}
if (container == null) return false;
string[] childKeys = keys[1].Split('|');
string personalKey = childKeys[0];
string entityKey = childKeys.Length > 1 ? childKeys[1] : "";
if (schema.CacheType == CacheType.Dictionary || schema.CacheType == CacheType.Entity)
{
container.Collection.TryGetValue(personalKey, out cacheItem);
itemPair = new KeyValuePair<string, CacheItemSet>(entityKey, cacheItem);
return true;
}
if (schema.CacheType == CacheType.Entity)
{
container.Collection.TryGetValue(entityKey, out cacheItem);
itemPair = new KeyValuePair<string, CacheItemSet>(entityKey, cacheItem);
return true;
}
if (schema.CacheType == CacheType.Queue)
{
TraceLog.WriteError("Not support CacheType.Queue get cache, key:{0}.", redisKey);
}
////存在分类id与实体主键相同情况, 要优先判断实体主键
//if (!string.IsNullOrEmpty(personalKey) && container.Collection.TryGetValue(entityKey, out cacheItem))
//{
// itemPair = new KeyValuePair<string, CacheItemSet>(entityKey, cacheItem);
// return true;
//}
//if (!string.IsNullOrEmpty(personalKey) && container.Collection.TryGetValue(personalKey, out cacheItem))
//{
// itemPair = new KeyValuePair<string, CacheItemSet>(entityKey, cacheItem);
// return true;
//}
}
return false;
}`
私服1和其他私服可能有跨服战和跨服活动,可以考虑支持一个专门用于跨服活动的服务器
fail:
var cache = new PersonalCacheStruct();
var user = cache.FindKey("138021"); //user has value
cache.RemoveCache(user); // return true
var temp = cache.FindKey("138021"); //return null
success:
var cache = new PersonalCacheStruct();
var user = cache.FindKey("138021"); //user has value
cache.RemoveCache(user); // return true
cache.RemoveCache(user); // return false
var temp = cache.FindKey("138021"); //temp has value
so , RemoveCache() can not work well !
Change the ShareCacheStruct LoadItemFactory function can solve my problem as below
`protected override bool LoadItemFactory(string key, bool isReplace)
{
//string redisKey = CreateRedisKey(key);
//var schema = SchemaTable();
//if (schema != null && schema.AccessLevel == AccessLevel.ReadWrite)
//{
// int periodTime = schema.PeriodTime;
// List dataList;
// if (DataContainer.TryLoadHistory(redisKey, out dataList))
// {
// InitCache(dataList, periodTime);
// return true;
// }
// else
// {
// return false;
// }
//}
string redisKey = CreateRedisKey(key);
TransReceiveParam receiveParam = new TransReceiveParam(redisKey);
receiveParam.Schema = SchemaTable();
int periodTime = receiveParam.Schema.PeriodTime;
int maxCount = receiveParam.Schema.Capacity;
var provider = Data.DbConnectionProvider.CreateDbProvider(receiveParam.Schema);
if (receiveParam.Schema.StorageType.HasFlag(StorageType.ReadOnlyDB) ||
receiveParam.Schema.StorageType.HasFlag(StorageType.ReadWriteDB))
{
if (provider == null)
{
TraceLog.WriteError("Not found db connection of {0} entity.", receiveParam.Schema.EntityName);
return false;
}
var filter = new DbDataFilter(maxCount);
if (!string.IsNullOrEmpty(key))
{
string[] keyValues = key.Split('-');
for (int i = 0; i < receiveParam.Schema.Keys.Length; i++)
{
filter.Condition = provider.FormatFilterParam(receiveParam.Schema.Keys[i]);
filter.Parameters.Add(receiveParam.Schema.Keys[i], keyValues[i]);
}
}
receiveParam.DbFilter = filter;
}
List<T> dataList;
if (DataContainer.TryReceiveData(receiveParam, out dataList))
{
InitCache(dataList, periodTime, isReplace);
return true;
}
else
{
return false;
}
}`
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.