feat: initial commit - HJHA game server full source
6 major server modules (PdkFriendServer/GlobalSever/ServerCore/GameModule/GameNetModule) + game logic (GameFix/GameDAL/ServerData) + network layer (NetWorkMessage) + data layer (ObjectModel) + utilities (MrWu/Core/Config/CloudAPI/dll) + adapters (zyxAdapter/base) .NET 8.0 C# solution, 16 projects, 958 source files
This commit is contained in:
4
PdkFriendServer/App.config
Normal file
4
PdkFriendServer/App.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
|
||||
</configuration>
|
||||
3
PdkFriendServer/FodyWeavers.xml
Normal file
3
PdkFriendServer/FodyWeavers.xml
Normal file
@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<Costura />
|
||||
</Weavers>
|
||||
176
PdkFriendServer/FodyWeavers.xsd
Normal file
176
PdkFriendServer/FodyWeavers.xsd
Normal file
@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||
<xs:element name="Weavers">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCleanup" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
40
PdkFriendServer/Form1.Designer.cs
generated
Normal file
40
PdkFriendServer/Form1.Designer.cs
generated
Normal file
@ -0,0 +1,40 @@
|
||||
namespace PdkFriendServer
|
||||
{
|
||||
partial class Form1
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(800, 450);
|
||||
this.Text = "Form1";
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
20
PdkFriendServer/Form1.cs
Normal file
20
PdkFriendServer/Form1.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PdkFriendServer
|
||||
{
|
||||
public partial class Form1 : Form
|
||||
{
|
||||
public Form1()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
26
PdkFriendServer/GameFix/LogicMemory.cs
Normal file
26
PdkFriendServer/GameFix/LogicMemory.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace GameFix.PaoDeKuaiF
|
||||
{
|
||||
public struct LogicMemory
|
||||
{
|
||||
/// <summary>
|
||||
/// 朋友房打了第几局
|
||||
/// </summary>
|
||||
public int WarCount;
|
||||
|
||||
/// <summary>
|
||||
/// 上游位置
|
||||
/// </summary>
|
||||
public byte ShangYou;
|
||||
|
||||
/// <summary>
|
||||
/// 记录炸弹个数
|
||||
/// </summary>
|
||||
public byte BombCount;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
WarCount = 0;
|
||||
ShangYou = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
624
PdkFriendServer/GameFix/PdkCardAlgorithm.cs
Normal file
624
PdkFriendServer/GameFix/PdkCardAlgorithm.cs
Normal file
@ -0,0 +1,624 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using GameFix.Poker;
|
||||
using GameMessage;
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
|
||||
namespace GameFix.PaoDeKuaiF
|
||||
{
|
||||
/// <summary>
|
||||
/// 跑得快牌运算逻辑
|
||||
/// </summary>
|
||||
public class PdkCardAlgorithm
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取提示的牌
|
||||
/// </summary>
|
||||
/// <param name="outCard">当前出的牌</param>
|
||||
/// <param name="shoupai">玩家在手里的牌,没有出下去的牌</param>
|
||||
/// <param name="maxShouPai">当前出牌人的手牌</param>
|
||||
/// <param name="aaaIsZhaDan">3A是不是炸弹,默认不是</param>
|
||||
/// <param name="isOne">只要一种提示 true是 false不是</param>
|
||||
/// <returns></returns>
|
||||
public static List<List<TCardInfoPdkF>> GetTipCardByBtn(PlayOutCardPdkF outCard, TCardInfoPdkF[] shoupai,
|
||||
TCardInfoPdkF[] maxShouPai, bool aaaIsZhaDan = false, bool isOne = false)
|
||||
{
|
||||
if (shoupai == null || shoupai.Length <= 0) return null;
|
||||
List<List<TCardInfoPdkF>> result = new List<List<TCardInfoPdkF>>();
|
||||
if (outCard.GameNum <= 0)
|
||||
{
|
||||
//如果是自己先出的话, 就从尾部一张一张提示过去
|
||||
for (int i = shoupai.Length - 1; i >= 0; i--)
|
||||
{
|
||||
List<TCardInfoPdkF> chu = new List<TCardInfoPdkF>();
|
||||
chu.Add(shoupai[i]);
|
||||
result.Add(chu);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (outCard.Type)
|
||||
{
|
||||
case CardType1.DanZhang:
|
||||
var danzhangs = PokerLogic.GetDanZhang(outCard, shoupai);
|
||||
if (danzhangs == null || danzhangs.Count <= 0)
|
||||
{
|
||||
danzhangs = PokerLogic.GetDanZhang(outCard, shoupai, true);
|
||||
}
|
||||
|
||||
if (danzhangs != null && danzhangs.Count > 0)
|
||||
{
|
||||
danzhangs.Sort((x, y) => x.GameNum.CompareTo(y.GameNum));
|
||||
foreach (var item in danzhangs)
|
||||
{
|
||||
List<TCardInfoPdkF> chu = new List<TCardInfoPdkF> { item };
|
||||
result.Add(chu);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.DuiZi:
|
||||
result = PokerLogic.GetCountCard(outCard, shoupai, 2);
|
||||
if (result == null || result.Count <= 0)
|
||||
{
|
||||
result = PokerLogic.GetCountCard(outCard, shoupai, 2, true);
|
||||
}
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.SanDai2:
|
||||
result = PokerLogic.GetCountCard(outCard, shoupai, 3, true);
|
||||
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
|
||||
break;
|
||||
case CardType1.ShunZi:
|
||||
result = PokerLogic.GetShunZi(outCard, shoupai);
|
||||
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
|
||||
break;
|
||||
case CardType1.LianDui:
|
||||
result = PokerLogic.GetLianCount(outCard, shoupai, 2, null);
|
||||
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
|
||||
break;
|
||||
case CardType1.FeiJi:
|
||||
result = PokerLogic.GetLianCount(outCard, shoupai, 3, maxShouPai);
|
||||
if (result != null) result.Sort((x, y) => x[0].GameNum.CompareTo(y[0].GameNum));
|
||||
break;
|
||||
case CardType1.ZhaDan:
|
||||
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
|
||||
if (cards.Count > 4)
|
||||
{
|
||||
int c = cards.Count / 4;
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
var tx = cards.Skip(i * 4).Take(4).ToList();
|
||||
if (tx != null && tx[0].GameNum > outCard.GameNum)
|
||||
{
|
||||
result.Add(tx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cards != null && cards.Count > 0 && cards[0].GameNum > outCard.GameNum)
|
||||
{
|
||||
result.Add(cards);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (isOne && result != null && result.Count > 0)
|
||||
{
|
||||
//只要一种提示
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result == null) result = new List<List<TCardInfoPdkF>>();
|
||||
if (aaaIsZhaDan)
|
||||
{
|
||||
var aaa = GetAAAZhaDan(shoupai);
|
||||
if (aaa != null && aaa.Count >= 3)
|
||||
{
|
||||
result.Add(aaa);
|
||||
}
|
||||
}
|
||||
|
||||
if (outCard.Type != CardType1.ZhaDan)
|
||||
{
|
||||
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
|
||||
if (cards != null && cards.Count > 0)
|
||||
{
|
||||
int c = cards.Count / 4;
|
||||
if (c <= 0)
|
||||
{
|
||||
result.Add(cards);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
result.Add(cards.Skip(i * 4).Take(4).ToList());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取提示的牌
|
||||
/// </summary>
|
||||
/// <param name="outCard">当前出的牌</param>
|
||||
/// <param name="shoupai">玩家在手里的牌,没有出下去的牌</param>
|
||||
/// <param name="maxShouPai">当前出牌人的手牌</param>
|
||||
/// <param name="aaaIsZhaDan">3A是不是炸弹,默认不是</param>
|
||||
/// <param name="isOne">只要一种提示 true是 false不是</param>
|
||||
/// <returns></returns>
|
||||
public static List<List<TCardInfoPdkF>> GetTipCard(PlayOutCardPdkF outCard, TCardInfoPdkF[] shoupai, TCardInfoPdkF[] maxShouPai,
|
||||
bool aaaIsZhaDan = false, bool isOne = false)
|
||||
{
|
||||
if (shoupai == null || shoupai.Length <= 0) return null;
|
||||
List<List<TCardInfoPdkF>> result = new List<List<TCardInfoPdkF>>();
|
||||
if (outCard.GameNum <= 0)
|
||||
{
|
||||
//如果是自己先出的话, 就从尾部一张一张提示过去
|
||||
for (int i = shoupai.Length - 1; i >= 0; i--)
|
||||
{
|
||||
List<TCardInfoPdkF> chu = new List<TCardInfoPdkF>();
|
||||
chu.Add(shoupai[i]);
|
||||
result.Add(chu);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
switch (outCard.Type)
|
||||
{
|
||||
//飞机带翅膀、炸弹,四带三、四带二
|
||||
case CardType1.DanZhang:
|
||||
var danzhangs = shoupai.Where(x => x.GameNum > outCard.GameNum);
|
||||
if (danzhangs.Count() > 0)
|
||||
{
|
||||
foreach (var item in danzhangs)
|
||||
{
|
||||
List<TCardInfoPdkF> chu = new List<TCardInfoPdkF>();
|
||||
chu.Add(item);
|
||||
result.Add(chu);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.DuiZi:
|
||||
result = PokerLogic.GetCountCard(outCard, shoupai, 2, true);
|
||||
break;
|
||||
case CardType1.SanDai2:
|
||||
result = PokerLogic.GetCountCard(outCard, shoupai, 3, true);
|
||||
break;
|
||||
case CardType1.ShunZi:
|
||||
result = PokerLogic.GetShunZi(outCard, shoupai);
|
||||
break;
|
||||
case CardType1.LianDui:
|
||||
result = PokerLogic.GetLianCount(outCard, shoupai, 2, null);
|
||||
break;
|
||||
case CardType1.FeiJi:
|
||||
result = PokerLogic.GetLianCount(outCard, shoupai, 3, maxShouPai);
|
||||
break;
|
||||
case CardType1.ZhaDan:
|
||||
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
|
||||
if (cards != null && cards.Count > 0 && cards[0].GameNum > outCard.GameNum)
|
||||
{
|
||||
result.Add(cards);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == null) result = new List<List<TCardInfoPdkF>>();
|
||||
if (isOne && result != null && result.Count > 0)
|
||||
{
|
||||
//只要一种提示
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aaaIsZhaDan)
|
||||
{
|
||||
var aaa = GetAAAZhaDan(shoupai);
|
||||
if (aaa != null && aaa.Count >= 3)
|
||||
{
|
||||
result.Add(aaa);
|
||||
}
|
||||
}
|
||||
|
||||
if (outCard.Type != CardType1.ZhaDan)
|
||||
{
|
||||
PokerLogic.GetPlayZhaDan(shoupai, out var cards);
|
||||
if (cards != null && cards.Count > 0)
|
||||
{
|
||||
result.Add(cards);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否是炸弹
|
||||
/// </summary>
|
||||
/// <param name="cards"></param>
|
||||
/// <param name="aaaIsZhaDan"></param>
|
||||
/// <param name="isCheckPaiCount"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsZhaDan(TCardInfoPdkF[] cards, bool aaaIsZhaDan, bool isCheckPaiCount = true)
|
||||
{
|
||||
if (cards == null || cards.Length < 3 || cards.Length > 4) return false;
|
||||
if (aaaIsZhaDan && cards.Length == 3)
|
||||
{
|
||||
return Is3A(cards);
|
||||
}
|
||||
|
||||
if (cards.Length == 4)
|
||||
{
|
||||
return IsZhaDan(cards, isCheckPaiCount);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查玩家是否有比出的牌更大的牌
|
||||
/// </summary>
|
||||
/// <param name="outCard">玩家出的牌</param>
|
||||
/// <param name="shouPai">自己的手牌-在手里的牌,并且是排序过的。</param>
|
||||
/// <param name="maxShouPai">出牌人的手牌</param>
|
||||
/// <param name="aaaIsZhaDan">3A是不是炸弹,默认不是</param>
|
||||
/// <returns>true有比玩家大的牌 false没有</returns>
|
||||
public static bool CheckHaveBigger(PlayOutCardPdkF outCard, TCardInfoPdkF[] shouPai, TCardInfoPdkF[] maxShouPai,
|
||||
bool aaaIsZhaDan = false)
|
||||
{
|
||||
if (shouPai == null || shouPai.Length <= 0) return false;
|
||||
List<List<TCardInfoPdkF>> cs = null;
|
||||
List<TCardInfoPdkF> cards = null;
|
||||
switch (outCard.Type)
|
||||
{
|
||||
case CardType1.DanZhang:
|
||||
if (shouPai.Where(x => x.GameNum > outCard.GameNum).Count() > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.DuiZi:
|
||||
cs = PokerLogic.GetCountCard(outCard, shouPai, 2, true);
|
||||
if (cs != null && cs.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.SanDai2:
|
||||
cs = PokerLogic.GetCountCard(outCard, shouPai, 3, true);
|
||||
if (cs != null && cs.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.ShunZi:
|
||||
cs = PokerLogic.GetShunZi(outCard, shouPai);
|
||||
if (cs != null && cs.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.LianDui:
|
||||
cs = PokerLogic.GetLianCount(outCard, shouPai, 2, null);
|
||||
if (cs != null && cs.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.FeiJi:
|
||||
cs = PokerLogic.GetLianCount(outCard, shouPai, 3, maxShouPai);
|
||||
if (cs != null && cs.Count > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
case CardType1.ZhaDan:
|
||||
var b = PokerLogic.GetPlayZhaDan(shouPai, out cards);
|
||||
if (!b) return false;
|
||||
foreach (var item in cards)
|
||||
{
|
||||
if (item.GameNum > outCard.GameNum) return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (aaaIsZhaDan)
|
||||
{
|
||||
var aaa = GetAAAZhaDan(shouPai);
|
||||
if (aaa != null && aaa.Count >= 3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (outCard.Type != CardType1.ZhaDan)
|
||||
{
|
||||
return PokerLogic.GetPlayZhaDan(shouPai, out cards);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过选中的牌返回出下去牌的类型 否则选中的牌就不能出下去
|
||||
/// 一般客户端用
|
||||
/// </summary>
|
||||
/// <param name="selectCards">选中的牌</param>
|
||||
/// <param name="shouPai">玩家手牌,不包含已经出下去的牌</param>
|
||||
/// <param name="wangfa">规则玩法</param>
|
||||
/// <param name="paycard">返回出牌内容</param>
|
||||
/// <returns>true可以出牌 false不能出牌</returns>
|
||||
public static bool GetOutCard(TCardInfoPdkF[] selectCards, TCardInfoPdkF[] shouPai, PdkRule wangfa,
|
||||
out PlayOutCardPdkF paycard)
|
||||
{
|
||||
paycard = new PlayOutCardPdkF();
|
||||
if (selectCards == null || selectCards.Length <= 0 || shouPai == null || shouPai.Length <= 0) return false;
|
||||
var chaCard = shouPai.Except(selectCards); //获取差集,如果个数大于0说明牌的张数是够的,如果是0,说明牌不够
|
||||
PokerLogic.SortCardByGameNum(ref selectCards);
|
||||
var bugou = chaCard.Count() <= 0;
|
||||
byte gameNum = 0;
|
||||
if (selectCards.Length == 1)
|
||||
{
|
||||
//单张可以出
|
||||
paycard.Ids = new byte[] { selectCards[0].ID };
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.DanZhang;
|
||||
return true;
|
||||
}
|
||||
else if (selectCards.Length == 2)
|
||||
{
|
||||
//对子
|
||||
if (PokerLogic.IsDuiZi(selectCards))
|
||||
{
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.DuiZi;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (selectCards.Length == 3)
|
||||
{
|
||||
if (wangfa.AAAIsZhaDan && Is3A(selectCards)) //3A是炸弹
|
||||
{
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.ZhaDan;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool xt = selectCards[0].GameNum == selectCards[1].GameNum &&
|
||||
selectCards[2].GameNum == selectCards[1].GameNum;
|
||||
if (xt && bugou)
|
||||
{
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.SanDai2;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsZhaDan(selectCards)) //炸弹
|
||||
{
|
||||
paycard.GameNum = selectCards[0].GameNum; //因为该值会根据大小排序
|
||||
paycard.Type = CardType1.ZhaDan;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (wangfa.SiDai2 && IsSiDai2(selectCards, !bugou, out gameNum))
|
||||
{
|
||||
//四带二
|
||||
paycard.GameNum = gameNum;
|
||||
paycard.Type = CardType1.SiDai2;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (wangfa.SiDai3 && IsSiDai3(selectCards, !bugou, out gameNum))
|
||||
{
|
||||
//四带二
|
||||
paycard.GameNum = gameNum;
|
||||
paycard.Type = CardType1.SiDai3;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PokerLogic.IsShunzi(selectCards))
|
||||
{
|
||||
//顺子
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.ShunZi;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PokerLogic.IsLianDui(selectCards)) //连对
|
||||
{
|
||||
paycard.GameNum = selectCards[0].GameNum;
|
||||
paycard.Type = CardType1.LianDui;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PokerLogic.IsSanDaiEr(selectCards, bugou, out gameNum)) //三带二、
|
||||
{
|
||||
paycard.GameNum = gameNum;
|
||||
paycard.Type = CardType1.SanDai2;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PokerLogic.IsFeiJi(selectCards, bugou, true, out gameNum)) //飞机带翅膀
|
||||
{
|
||||
paycard.GameNum = gameNum;
|
||||
paycard.Type = CardType1.FeiJi;
|
||||
paycard.Ids = selectCards.Select(x => x.ID).ToArray();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是3张A
|
||||
/// </summary>
|
||||
/// <param name="cards"></param>
|
||||
/// <returns>true是 false不是</returns>
|
||||
static bool Is3A(TCardInfoPdkF[] cards)
|
||||
{
|
||||
if (cards == null || cards.Length != 3) return false;
|
||||
return cards[0].GameNum == 14 && cards[1].GameNum == 14 && cards[2].GameNum == 14;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取3A炸弹
|
||||
/// </summary>
|
||||
/// <param name="cards">玩家手里没有打下去的牌</param>
|
||||
/// <returns></returns>
|
||||
static List<TCardInfoPdkF> GetAAAZhaDan(TCardInfoPdkF[] cards)
|
||||
{
|
||||
if (cards == null || cards.Length < 3) return null;
|
||||
List<TCardInfoPdkF> result = new List<TCardInfoPdkF>();
|
||||
for (int i = 0; i < cards.Length; i++)
|
||||
{
|
||||
if (cards[i].GameNum == 14)
|
||||
{
|
||||
result.Add(cards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (result.Count >= 3)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static bool IsSiDai3(TCardInfoPdkF[] selectCards, bool isPaiBuGou, out byte gameNum)
|
||||
{
|
||||
gameNum = 0;
|
||||
if (selectCards == null || selectCards.Length < 5 || selectCards.Length > 7) return false;
|
||||
if (isPaiBuGou && selectCards.Length != 7) return false;
|
||||
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
|
||||
if (!b) return b;
|
||||
gameNum = cards[0].GameNum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是四带二
|
||||
/// </summary>
|
||||
/// <param name="selectCards"></param>
|
||||
/// <param name="isPaiBuGou">true牌够,false牌不够</param>
|
||||
/// <returns>true是 false不是</returns>
|
||||
#pragma warning disable CS1573 // 参数在 XML 注释中没有匹配的 param 标记(但其他参数有)
|
||||
static bool IsSiDai2(TCardInfoPdkF[] selectCards, bool isPaiBuGou, out byte gameNum)
|
||||
#pragma warning restore CS1573 // 参数在 XML 注释中没有匹配的 param 标记(但其他参数有)
|
||||
{
|
||||
gameNum = 0;
|
||||
if (selectCards == null || selectCards.Length < 5 || selectCards.Length > 6) return false;
|
||||
if (isPaiBuGou && selectCards.Length != 6) return false;
|
||||
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
|
||||
if (!b) return b;
|
||||
gameNum = cards[0].GameNum;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否是炸弹
|
||||
/// </summary>
|
||||
/// <param name="selectCards"></param>
|
||||
/// <param name="isCheckPaiCount">是否要校验牌的张数对不对</param>
|
||||
/// <returns></returns>
|
||||
static bool IsZhaDan(TCardInfoPdkF[] selectCards, bool isCheckPaiCount = true)
|
||||
{
|
||||
if (selectCards == null || selectCards.Length < 4) return false;
|
||||
int gameNum = 0;
|
||||
foreach (var item in selectCards)
|
||||
{
|
||||
if (gameNum == 0)
|
||||
{
|
||||
gameNum = item.GameNum;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gameNum != item.GameNum)
|
||||
{
|
||||
//炸弹的牌不是一样的牌
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var b = PokerLogic.GetPlayZhaDan(selectCards, out var cards);
|
||||
if (!b) return b;
|
||||
if (isCheckPaiCount)
|
||||
{
|
||||
//校验返回的炸弹牌数量和传入的牌数量是不是一样多
|
||||
return selectCards.Length == cards.Count;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否有炸弹
|
||||
/// </summary>
|
||||
/// <param name="selectCards"></param>
|
||||
/// <param name="aaaIsBomb">AAA是否是炸弹 true是 false不是</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsHaveBomb(TCardInfoPdkF[] selectCards, bool aaaIsBomb)
|
||||
{
|
||||
if (selectCards == null || selectCards.Length < 3) return false;
|
||||
if (!aaaIsBomb && selectCards.Length < 4) return false;
|
||||
Dictionary<int, int> dic = new Dictionary<int, int>();
|
||||
for (int i = 0; i < selectCards.Length; i++)
|
||||
{
|
||||
if (dic.ContainsKey(selectCards[i].GameNum))
|
||||
{
|
||||
dic[selectCards[i].GameNum]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dic[selectCards[i].GameNum] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in dic)
|
||||
{
|
||||
if (aaaIsBomb && item.Key == 14 && item.Value == 3) return true;
|
||||
if (item.Value >= 4) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
162
PdkFriendServer/GameFix/PdkRule.cs
Normal file
162
PdkFriendServer/GameFix/PdkRule.cs
Normal file
@ -0,0 +1,162 @@
|
||||
using System.Text;
|
||||
|
||||
namespace GameFix.PaoDeKuaiF
|
||||
{
|
||||
/// <summary>
|
||||
/// 跑得快玩法规则
|
||||
/// </summary>
|
||||
public class PdkRule
|
||||
{
|
||||
/// <summary>
|
||||
/// 经典玩法 (必压) false不是 true是
|
||||
/// 经典玩法(16张玩法):一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张
|
||||
/// </summary>
|
||||
public bool JingDianWanFa;
|
||||
|
||||
/// <summary>
|
||||
/// 是否必压 true必压 false不必压
|
||||
/// </summary>
|
||||
public bool BiYa;
|
||||
|
||||
/// <summary>
|
||||
/// 15张玩法 false不是 true是
|
||||
/// 15张玩法(有大必压):一副牌,去掉大小王、三个2(保留黑桃2)和三个A(保留黑桃 A ),去掉一个K,共45张,每人15张
|
||||
/// </summary>
|
||||
public bool Zhang15;
|
||||
|
||||
/// <summary>
|
||||
/// 关牌(不必压)false不是 true是
|
||||
/// 一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张
|
||||
/// </summary>
|
||||
public bool GuanPai;
|
||||
|
||||
/// <summary>
|
||||
/// 首局黑桃3玩家先出,下局赢家先出。false不是 true是
|
||||
/// </summary>
|
||||
public bool ShouJu3;
|
||||
|
||||
//注意:2个人都没有黑桃3的情况下,那就从小到大找黑桃的,比如没有黑桃3,就找黑桃4.看谁有就随先出
|
||||
|
||||
/// <summary>
|
||||
/// 每局黑桃3先出。 如果是2个玩家玩,
|
||||
/// </summary>
|
||||
public bool MeiJu3;
|
||||
|
||||
/// <summary>
|
||||
/// 4带3张 false不是 true是 AAA只能带2张
|
||||
/// </summary>
|
||||
public bool SiDai3;
|
||||
|
||||
/// <summary>
|
||||
/// 4带两张 false不是 true是 AAA只能带2张
|
||||
/// </summary>
|
||||
public bool SiDai2;
|
||||
|
||||
/// <summary>
|
||||
/// 显示剩余牌数 false不是 true是
|
||||
/// </summary>
|
||||
public bool XianShenYuPai;
|
||||
|
||||
/// <summary>
|
||||
/// 红桃十扎鸟 false不是 true是
|
||||
/// 有红桃十玩家手牌输赢分翻倍
|
||||
/// </summary>
|
||||
public bool HongTao10ZhaNiao;
|
||||
|
||||
/// <summary>
|
||||
/// 炸弹加分 true加10分 false不加分
|
||||
/// </summary>
|
||||
public bool ZhaDanDeFen;
|
||||
|
||||
/// <summary>
|
||||
/// 3张A是不是炸弹 true是 false不是
|
||||
/// </summary>
|
||||
public bool AAAIsZhaDan;
|
||||
|
||||
/// <summary>
|
||||
/// 下家报单,上家有压必压 true是 false不是。
|
||||
/// 如果勾选了,那么上家要出最大的单张
|
||||
/// </summary>
|
||||
public bool XiaJiaBaoDan;
|
||||
|
||||
/// <summary>
|
||||
/// 包庄 true包庄 false不包庄
|
||||
/// 玩家选择包庄,打完不能让其他玩家出牌,关了算春天,输赢分*2,如果让其他玩家出牌了,包庄失败,输赢分也要*2。
|
||||
/// 如果有2个闲家包庄,庄家的下家为包庄玩家。如果一庄一闲。那庄家为包庄。
|
||||
/// </summary>
|
||||
public bool BaoZhuang;
|
||||
|
||||
/// <summary>
|
||||
/// 托管的时间 0不托管 1超过1分钟托管 3超过3分钟托管 5超过5分钟托管
|
||||
/// </summary>
|
||||
public int TuoGuanNum;
|
||||
|
||||
/// <summary>
|
||||
/// 首局黑桃三首次必出
|
||||
/// </summary>
|
||||
public bool HeiTao3BiChu;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (JingDianWanFa)
|
||||
{
|
||||
sb.Append("经典玩法, ");
|
||||
}
|
||||
if (Zhang15)
|
||||
{
|
||||
sb.Append("15张玩法, ");
|
||||
}
|
||||
if (GuanPai)
|
||||
{
|
||||
sb.Append("关牌玩法, ");
|
||||
}
|
||||
if (MeiJu3)
|
||||
{
|
||||
sb.Append("每局黑桃3先出, ");
|
||||
}
|
||||
if (ShouJu3)
|
||||
{
|
||||
sb.Append("首局黑桃3先出, ");
|
||||
}
|
||||
if (SiDai3)
|
||||
{
|
||||
sb.Append("四带三, ");
|
||||
}
|
||||
if (SiDai2)
|
||||
{
|
||||
sb.Append("四带二, ");
|
||||
}
|
||||
if (HongTao10ZhaNiao)
|
||||
{
|
||||
sb.Append("红桃10扎鸟, ");
|
||||
}
|
||||
if (ZhaDanDeFen)
|
||||
{
|
||||
sb.Append("炸弹加10, ");
|
||||
}
|
||||
if (AAAIsZhaDan)
|
||||
{
|
||||
sb.Append("3A为最大炸弹, ");
|
||||
}
|
||||
if (BaoZhuang)
|
||||
{
|
||||
sb.Append("包庄, ");
|
||||
}
|
||||
sb.Append(BiYa ? "必压, " : "不必压, ");
|
||||
if (XianShenYuPai)
|
||||
{
|
||||
sb.Append("显示剩余牌数, ");
|
||||
}
|
||||
if (XiaJiaBaoDan)
|
||||
{
|
||||
sb.Append("下家报单,上家有压必压, ");
|
||||
}
|
||||
if (HeiTao3BiChu)
|
||||
{
|
||||
sb.Append("首局黑桃三首次必出 ");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
39
PdkFriendServer/GlobalManager/GameServerProxy.cs
Normal file
39
PdkFriendServer/GlobalManager/GameServerProxy.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using GlobalSever.Form;
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PdkFriendServer.GlobalManager
|
||||
{
|
||||
public class GameServerProxy : ServerProxy
|
||||
{
|
||||
|
||||
//游戏服务器名称,显示用的标题
|
||||
protected override ServerUtilFactory CreateUtilFactory()
|
||||
{
|
||||
return new MyFactory();
|
||||
}
|
||||
|
||||
public GameServerProxy() : base()
|
||||
{
|
||||
ServerName = "跑得快朋友房";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override ServerTable[] GetServerTable()
|
||||
{
|
||||
return new ServerTable[]{
|
||||
new GameControl(this),
|
||||
new GameTestTable(this)
|
||||
//, new DaZhaForm(this)
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
20
PdkFriendServer/GlobalManager/GameSeverManager.cs
Normal file
20
PdkFriendServer/GlobalManager/GameSeverManager.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Server;
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
|
||||
namespace PdkFriendServer.GlobalManager
|
||||
{
|
||||
public class GameSeverManager : GameBase
|
||||
{
|
||||
protected override GameUtilFactory CreateFactory()
|
||||
{
|
||||
return new PdkFactory();
|
||||
}
|
||||
|
||||
protected override void PreLoadMessagePack()
|
||||
{
|
||||
PdkGamePack pack = new PdkGamePack();
|
||||
byte[] data = MessageHelper.MessagePackSerialize(pack);
|
||||
pack = MessageHelper.MessagePackDeserialize<PdkGamePack>(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
PdkFriendServer/GlobalManager/MyFactory.cs
Normal file
41
PdkFriendServer/GlobalManager/MyFactory.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using Server;
|
||||
using Server.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
namespace PdkFriendServer.GlobalManager
|
||||
{
|
||||
public class MyFactory : ServerUtilFactory
|
||||
{
|
||||
public override Server.GlobalManager GetGlobalManager()
|
||||
{
|
||||
return new GameSeverManager();
|
||||
}
|
||||
|
||||
public override object Produce(string ObjectName)
|
||||
{
|
||||
switch (ObjectName)
|
||||
{
|
||||
case "GameInfo":
|
||||
return new GameSerInfo();
|
||||
case "castleInfo":
|
||||
return new CastleSerInfo();
|
||||
case "tingInfo":
|
||||
return new TingSerInfo();
|
||||
case "deskInfo":
|
||||
return new DeskSerInfo();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override Server.GlobalManager.MessageProcessor CreateMessageProcessor()
|
||||
{
|
||||
return new GameBase.GameMessageProcessor();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
17
PdkFriendServer/GlobalManager/PdkFactory.cs
Normal file
17
PdkFriendServer/GlobalManager/PdkFactory.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using Server;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PdkFriendServer.GlobalManager
|
||||
{
|
||||
public class PdkFactory : GameUtilFactory
|
||||
{
|
||||
public override GameDo GetGameDo(Desk desk)
|
||||
{
|
||||
return new PdkGameDo(desk);
|
||||
}
|
||||
}
|
||||
}
|
||||
274
PdkFriendServer/GlobalManager/PdkGameDo.cs
Normal file
274
PdkFriendServer/GlobalManager/PdkGameDo.cs
Normal file
@ -0,0 +1,274 @@
|
||||
/********************************
|
||||
*
|
||||
* 作者:徐高庆
|
||||
* 创建时间: 2024年5月27日15:05:28
|
||||
*
|
||||
********************************/
|
||||
using GameData;
|
||||
using MrWu.Debug;
|
||||
using PdkFriendServer.Logic;
|
||||
using Server;
|
||||
using Server.Pack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
using Server.Core;
|
||||
using Server.Data;
|
||||
using MessageHelper = Server.MessageHelper;
|
||||
|
||||
namespace PdkFriendServer.GlobalManager
|
||||
{
|
||||
public class PdkGameDo : GameDo
|
||||
{
|
||||
/// <summary>
|
||||
/// 跑得快朋友房主要逻辑
|
||||
/// </summary>
|
||||
PdkGameMain Main;
|
||||
|
||||
/// <summary>
|
||||
/// 计时器
|
||||
/// </summary>
|
||||
int timeNum;
|
||||
|
||||
public Desk desk = null;
|
||||
|
||||
public PdkGameDo(Desk desk) : base(desk)
|
||||
{
|
||||
Main = new PdkGameMain(this);
|
||||
this.desk = desk;
|
||||
}
|
||||
|
||||
public override void DoZyxPack(GamePack data)
|
||||
{
|
||||
|
||||
PdkLogicInfo logicInfo;
|
||||
if (data.IsBinary)
|
||||
{
|
||||
logicInfo = MessagePackHelper.Deserialize<PdkLogicInfo>(data.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.JsonData.Length < 10)
|
||||
{ //托管包
|
||||
byte[] tgData = JsonPack.GetData<byte[]>(data.JsonData);
|
||||
Debug.Info("收到托管包" + data.JsonData.Length);
|
||||
if (tgData[1] == 0)
|
||||
{
|
||||
Main.GamePack.Info.PlayTuoGauan[tgData[0]] = tgData[1];
|
||||
desk[tgData[0]].SetDeposit( tgData[1] == 1 ? true : false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
logicInfo = JsonPack.GetData<PdkLogicInfo>(data.JsonData);
|
||||
}
|
||||
|
||||
var b = Main.CheckPack(logicInfo);
|
||||
if (!b)
|
||||
{
|
||||
Debug.Warning("客户端包内容检查不过。收包错误");
|
||||
return;
|
||||
}
|
||||
|
||||
//正式连客户端以后要屏蔽这些代码。return
|
||||
switch (Main.GamePack.Info.GameZT) //只要客户端输入的值
|
||||
{
|
||||
case 3://包庄
|
||||
Main.GamePack.Info.BaoZhuang[logicInfo.WhoPlay - 1] = logicInfo.BaoZhuang[logicInfo.WhoPlay - 1];
|
||||
break;
|
||||
case 4: //打牌
|
||||
Main.GamePack.Info.ActivePlayCard = logicInfo.ActivePlayCard;
|
||||
Main.TimeNum = 0; //重置time计时器
|
||||
break;
|
||||
}
|
||||
Debug.Info("收到子游戏包GameDo!");
|
||||
this.Main.GameDo();
|
||||
}
|
||||
|
||||
public override void StartWar()
|
||||
{
|
||||
timeNum = 0;
|
||||
base.StartWar();
|
||||
Main.GameStart();
|
||||
}
|
||||
|
||||
public void SendGamePack()
|
||||
{
|
||||
var str = JsonPack.GetJson(Main.GamePack);
|
||||
int len = desk.Count;
|
||||
PlayerDataAsyc tmppl;
|
||||
|
||||
byte[] data = MessageHelper.MessagePackSerialize(this.Main.GamePack);
|
||||
for (int i = 0; i < Main.GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
tmppl = desk[i];
|
||||
if (tmppl==null||tmppl.isRobot)continue;
|
||||
if (tmppl.ClientVer > 46)
|
||||
{
|
||||
ClearOtherCard(tmppl.seat, data,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] datastr= Encoding.UTF8.GetBytes(str);
|
||||
ClearOtherCard(tmppl.seat, datastr,true);
|
||||
}
|
||||
}
|
||||
|
||||
SaveGameData(data);
|
||||
SaveHuiFang(0, str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发包前清空不是自己手里的牌
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="packData"></param>
|
||||
void ClearOtherCard(int pos, byte[] packData,bool isOld)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Main.GamePack.Info.OverPos > 0)
|
||||
{//如果是游戏结束的话就不清空玩家牌了,因为最后要亮玩家手牌
|
||||
SendPack(pos, packData);
|
||||
return;
|
||||
}
|
||||
var pack = isOld ? JsonPack.GetData<PdkGamePack>(Encoding.UTF8.GetString(packData))
|
||||
: MessagePackHelper.Deserialize<PdkGamePack>(packData);
|
||||
for (int i = 0; i < Main.GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (i == pos) continue;
|
||||
for (int j = 0; j < pack.CardPack.Cards[i].CardInfos.Length; j++)
|
||||
{
|
||||
if (pack.CardPack.Cards[i].CardInfos[j].GameState == 0) continue; //打下去的牌不清空
|
||||
pack.CardPack.Cards[i].CardInfos[j] = new TCardInfoPdkF();
|
||||
}
|
||||
}
|
||||
//var str = JsonPack.GetJson(pack);
|
||||
SendPack(pos, packData);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Error($"发包前清空不是自己手里的牌,msg:{e.Message} code:{e.StackTrace}");
|
||||
SendPack(pos, packData);
|
||||
}
|
||||
}
|
||||
|
||||
public void SaveGameData(byte[] data)
|
||||
{
|
||||
SaveData(data);
|
||||
}
|
||||
|
||||
public override void LoadMem(byte[] data,bool isOld)
|
||||
{
|
||||
Main.SetFriendGz();
|
||||
if (isOld)
|
||||
{
|
||||
Main.GamePack = JsonPack.GetData<PdkGamePack>(Encoding.UTF8.GetString(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
Main.GamePack = MessageHelper.MessagePackDeserialize<PdkGamePack>(data);
|
||||
}
|
||||
Main.LoadInit();
|
||||
|
||||
}
|
||||
|
||||
public override void LoadMemSuccess()
|
||||
{
|
||||
Main.SetOperation();
|
||||
}
|
||||
|
||||
public void GameOver()
|
||||
{
|
||||
for (int i = 0; i < Main.GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
var num = Main.GamePack.Info.Score[i];
|
||||
SetPlayer(i, 8, num, string.Empty);
|
||||
}
|
||||
SendGamePack();
|
||||
WarOver();
|
||||
}
|
||||
|
||||
public override void Reconnect(int seat)
|
||||
{
|
||||
if (seat < 0)
|
||||
{
|
||||
int len = desk.Count;
|
||||
PlayerDataAsyc tmppl;
|
||||
byte[] data = MessagePackHelper.Serialize(this.Main.GamePack);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
tmppl= desk[i];
|
||||
if(tmppl==null||tmppl.isRobot)continue;
|
||||
if (desk[seat].ClientVer > 46)
|
||||
{
|
||||
// 新客户端 MessagePack
|
||||
ClearOtherCard(seat, data,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 老的客户端 Encding
|
||||
byte[] datastr= Encoding.UTF8.GetBytes(JsonPack.GetJson(this.Main.GamePack));
|
||||
ClearOtherCard(seat, datastr,true);
|
||||
}
|
||||
}
|
||||
}else if(seat < desk.PlayerCnt)
|
||||
{
|
||||
if (desk[seat] == null)
|
||||
{
|
||||
Debug.Error("逻辑错误!------{0},PlayerCnt:{1}", seat, desk.PlayerCnt);
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] data = MessagePackHelper.Serialize(this.Main.GamePack);
|
||||
if (!desk[seat].isRobot)
|
||||
{
|
||||
if (desk[seat].ClientVer > 46)
|
||||
{
|
||||
// 新客户端 MessagePack
|
||||
ClearOtherCard(seat, data,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 老的客户端 Encding
|
||||
byte[] datastr= Encoding.UTF8.GetBytes(JsonPack.GetJson(this.Main.GamePack));
|
||||
ClearOtherCard(seat, datastr,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Warning("发包位置大于桌子人数!" + seat + "," + desk.PlayerCnt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void OnTime(int interval)
|
||||
{
|
||||
//200毫秒一次,一秒执行5次
|
||||
timeNum++;
|
||||
if (timeNum >= 5)
|
||||
{
|
||||
timeNum = 0;
|
||||
this.Main.DoTime();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override void WarOver()
|
||||
{
|
||||
desk.WarOver();
|
||||
isFighting = false;
|
||||
}
|
||||
|
||||
public Desk GetDesk()
|
||||
{
|
||||
return this.desk;
|
||||
}
|
||||
}
|
||||
}
|
||||
814
PdkFriendServer/Logic/PdkGameMain.cs
Normal file
814
PdkFriendServer/Logic/PdkGameMain.cs
Normal file
@ -0,0 +1,814 @@
|
||||
using GameData;
|
||||
using MrWu.Debug;
|
||||
using PdkFriendServer.GlobalManager;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
using GameFix.PaoDeKuaiF;
|
||||
using GameMessage;
|
||||
using Server.Data;
|
||||
|
||||
namespace PdkFriendServer.Logic
|
||||
{
|
||||
/// <summary>
|
||||
/// 跑得快朋友房主逻辑
|
||||
/// </summary>
|
||||
public partial class PdkGameMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏主包
|
||||
/// </summary>
|
||||
public PdkGamePack GamePack;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器本地内存
|
||||
/// </summary>
|
||||
public LogicMemory logicMemory;
|
||||
|
||||
/// <summary>
|
||||
/// 规则
|
||||
/// </summary>
|
||||
public PdkRule Rule;
|
||||
|
||||
/// <summary>
|
||||
/// 桌子对象
|
||||
/// </summary>
|
||||
public PdkGameDo DeskGameDo = null;
|
||||
|
||||
public PdkGameMain(PdkGameDo _gamedo)
|
||||
{
|
||||
this.DeskGameDo = _gamedo;
|
||||
this.GamePack = new PdkGamePack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏开始
|
||||
/// </summary>
|
||||
public void GameStart()
|
||||
{
|
||||
byte shangyou = 0; //上游位置,从1开始
|
||||
byte overJu = (byte)(this.DeskGameDo == null ? 0 : DeskGameDo.GetDeskInt(8)); //打完了几局,0就是一局都没有打完,也就是首局
|
||||
shangyou = GamePack.Info.OverPos;
|
||||
var tg = GamePack.Info.PlayTuoGauan;
|
||||
GamePack = new PdkGamePack();
|
||||
if (this.DeskGameDo != null)
|
||||
{
|
||||
SetFriendGz();
|
||||
GamePack.Init(GamePack.Info.PlayNum);
|
||||
}
|
||||
else
|
||||
{ //测试的规则
|
||||
GamePack.Init(3);
|
||||
GamePack.Info.PlayNum = 3;
|
||||
//设置玩法规则
|
||||
Rule = new PdkRule();
|
||||
Rule.GuanPai = true; //经典玩法
|
||||
Rule.BiYa = true;//不必压
|
||||
Rule.ShouJu3 = true;
|
||||
Rule.SiDai3 = true;
|
||||
Rule.BaoZhuang = true;
|
||||
Rule.ZhaDanDeFen = true;
|
||||
}
|
||||
LoadInit();
|
||||
if (overJu == 0)
|
||||
{
|
||||
logicMemory.BombCount = 0;
|
||||
}
|
||||
logicMemory.WarCount = overJu;
|
||||
logicMemory.ShangYou = shangyou;
|
||||
if (overJu != 0)
|
||||
{
|
||||
GamePack.Info.PlayTuoGauan = tg;
|
||||
}
|
||||
GamePack.Info.GameZT = 2;
|
||||
Log(Rule.ToString());
|
||||
//this.GameFaPai(); //屏蔽掉,让dotime驱动流程玩下周
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置规则自动准备时间
|
||||
/// </summary>
|
||||
void SetAutoReadTime()
|
||||
{
|
||||
if (this.Rule.TuoGuanNum <= 0) return;
|
||||
if (this.DeskGameDo == null) return;
|
||||
if (this.DeskGameDo.desk == null) return;
|
||||
if (this.DeskGameDo.desk.deskinfo == null) return;
|
||||
if (this.DeskGameDo.desk.deskinfo.rule == null) return;
|
||||
if (this.DeskGameDo.desk.deskinfo.rule.RuleEx == null) return;
|
||||
// if (!this.DeskGameDo.desk.deskinfo.rule.RuleEx.DepositAutoDissolve) return;
|
||||
if (this.DeskGameDo.desk.deskinfo.rule.RuleEx.AutoDeposit > 0) return;
|
||||
this.DeskGameDo.desk.deskinfo.rule.RuleEx.AutoDeposit = this.Rule.TuoGuanNum * 60;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计时器 1秒钟执行一次
|
||||
/// </summary>
|
||||
public void DoTime()
|
||||
{
|
||||
SetAutoReadTime();
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
//case 1:
|
||||
// GameStart();
|
||||
// break;
|
||||
case 2:
|
||||
GameFaPai();
|
||||
break;
|
||||
case 3:
|
||||
BaoZhuangTuoGuan();
|
||||
break;
|
||||
case 4:
|
||||
//if (Rule.TuoGuanNum > 0)
|
||||
//{//需要托管
|
||||
DaPaiTuoGuan();
|
||||
//}
|
||||
//玩家先手,并且是最后一张牌,就自动帮玩家出牌
|
||||
if (GamePack.Info.MaxPlayCard.GameNum <= 0)
|
||||
{
|
||||
var cards = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray();
|
||||
var b = PdkCardAlgorithm.GetOutCard(cards, cards, Rule, out var payCard);
|
||||
var zhad = PdkCardAlgorithm.IsHaveBomb(cards, Rule.AAAIsZhaDan);
|
||||
if (b && payCard.Ids.Length == cards.Length && payCard.Type != CardType1.SiDai2 && payCard.Type != CardType1.SiDai3 && !zhad)
|
||||
{
|
||||
payCard.Pos = (byte)GamePack.Info.WhoPlay;
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
Log($"最后一张牌,就自动帮玩家出牌 who:{GamePack.Info.WhoPlay}先出 ,托管出的牌:{payCard}");
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
Debug.Info("最后一手GameDo");
|
||||
GameDo();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (this.TimeNum >= 2)
|
||||
{
|
||||
GameOver();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Log("DoTime default !");
|
||||
break;
|
||||
}
|
||||
TimeNum++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏发牌
|
||||
/// </summary>
|
||||
public void GameFaPai()
|
||||
{
|
||||
byte bc = 0; //计算这局的炸弹个数
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
Log($"发牌i:{i} bnum:{bc} lc:{logicMemory.BombCount}", DebugLevel.ImportantLog);
|
||||
}
|
||||
InitCard();
|
||||
bc = 0;
|
||||
bool b = false;
|
||||
for (int j = 0; j < GamePack.Info.PlayNum; j++)
|
||||
{
|
||||
byte bnum = CalcPlayBombRule(j);
|
||||
Log($"玩家:{j},bombCount:{bnum}");
|
||||
//if (bnum > 1) //单个人一手牌不能有超过2个炸弹
|
||||
//{
|
||||
// bc += (byte)bnum;
|
||||
// break;
|
||||
//}
|
||||
if (bnum > 0)
|
||||
{
|
||||
bc += bnum;
|
||||
}
|
||||
}
|
||||
if (logicMemory.BombCount + bc <= 1)
|
||||
{
|
||||
logicMemory.BombCount += bc;
|
||||
b = true;
|
||||
}
|
||||
if (b)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
CheckFeiJi();
|
||||
if (Rule.HongTao10ZhaNiao)
|
||||
{ //红桃十扎鸟
|
||||
GamePack.Info.HongTaoShiPos = GetHongTaoShiPos();
|
||||
}
|
||||
if (Rule.MeiJu3)
|
||||
{ //每局黑桃3出
|
||||
GamePack.Info.FistPlay = GetHeiTao3Pos();
|
||||
Log($"第一个出牌位置:{GamePack.Info.FistPlay}");
|
||||
}
|
||||
else if (Rule.ShouJu3)
|
||||
{ //首局黑桃三先出,下局赢家出
|
||||
GamePack.Info.FistPlay = logicMemory.WarCount == 0 ? GetHeiTao3Pos() : logicMemory.ShangYou;
|
||||
Log($"第一个出牌位置:{GamePack.Info.FistPlay},开始次数:{logicMemory.WarCount},上游玩家:{logicMemory.ShangYou}");
|
||||
}
|
||||
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
|
||||
GamePack.Info.GameZT = (byte)(Rule.BaoZhuang ? 3 : 4);
|
||||
TimeNum = 0;
|
||||
SendPack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 包庄流程
|
||||
/// </summary>
|
||||
public void GameBaoZhuang()
|
||||
{
|
||||
int bcount = 0;//包庄的人数
|
||||
byte[] pos = new byte[GamePack.Info.PlayNum]; //包庄人的位置
|
||||
bool zhuangB = false;
|
||||
if (GamePack.Info.BaoZhuang[GamePack.Info.FistPlay - 1] == 1)
|
||||
{ //庄家包庄了,直接进入下一流程
|
||||
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
|
||||
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
|
||||
GamePack.Info.GameZT = 4; //进入打牌
|
||||
SetFalseOperation();
|
||||
SendPack();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (GamePack.Info.BaoZhuang[i] == 0)
|
||||
{
|
||||
// GamePack.Info.WhoPlay = GetNextPos(GamePack.Info.WhoPlay);
|
||||
SendPack();
|
||||
return; //还有玩家没有操作,不处理流程
|
||||
}
|
||||
if (GamePack.Info.BaoZhuang[i] == 1)
|
||||
{
|
||||
pos[bcount] = (byte)(i + 1);
|
||||
if (!zhuangB && pos[bcount] == GamePack.Info.FistPlay)
|
||||
{
|
||||
zhuangB = true;
|
||||
}
|
||||
bcount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bcount == 1)
|
||||
{
|
||||
GamePack.Info.WhoPlay = pos[0];
|
||||
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
|
||||
}
|
||||
else if (bcount > 1)
|
||||
{ //多个人包庄
|
||||
if (zhuangB)
|
||||
{//如果庄家包庄了,那么就是庄家为包庄
|
||||
GamePack.Info.WhoPlay = GamePack.Info.FistPlay;
|
||||
}
|
||||
else
|
||||
{ //如果没有包庄的话,那么靠近庄家的下一家为包庄玩家
|
||||
byte npos = GetNextPos(GamePack.Info.FistPlay); //庄的下家
|
||||
for (int j = 0; j < pos.Length; j++)
|
||||
{
|
||||
bool b = false;
|
||||
for (byte i = 0; i < pos.Length; i++)
|
||||
{
|
||||
if (pos[i] == npos)
|
||||
{
|
||||
GamePack.Info.WhoPlay = pos[i];
|
||||
b = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!b)
|
||||
{
|
||||
npos = GetNextPos(npos);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
GamePack.Info.BaoPos = GamePack.Info.WhoPlay;
|
||||
}
|
||||
Log($"进入打牌,play:{GamePack.Info.WhoPlay} ,包庄玩家的位置:{GamePack.Info.BaoPos}");
|
||||
GamePack.Info.GameZT = 4; //进入打牌
|
||||
SetFalseOperation();
|
||||
SendPack();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打牌流程
|
||||
/// </summary>
|
||||
void GameDaPai()
|
||||
{
|
||||
Log("进入打牌流程,玩家出牌内容是:" + GamePack.Info.ActivePlayCard.ToString());
|
||||
//如果玩家有出牌:1修改牌内存,2修改最大出牌信息
|
||||
//记录炸弹计分
|
||||
//判断一轮打完
|
||||
//判断一局游戏打完
|
||||
//转换控制权 一个玩家出完牌后
|
||||
byte chupaiPos = 0;
|
||||
if (GamePack.Info.ActivePlayCard.Type != CardType1.None)
|
||||
{
|
||||
chupaiPos = GamePack.Info.ActivePlayCard.Pos;
|
||||
SetCardToOut(GamePack.Info.ActivePlayCard.Pos, GamePack.Info.ActivePlayCard.Ids);
|
||||
if (Rule.ZhaDanDeFen && GamePack.Info.ActivePlayCard.Type == CardType1.ZhaDan)
|
||||
{
|
||||
//炸弹得分,并且出的是炸弹
|
||||
/*炸弹+10:打出炸弹+10分,不勾选0分
|
||||
在有大必压得玩法下,一轮中打出的炸弹只算当局最大的炸弹分,
|
||||
不必压得玩法下,只要打出炸弹都算分*/
|
||||
AddZhaDanCount(GamePack.Info.ActivePlayCard.Pos, 1);
|
||||
// GamePack.Info.ZhaDans[GamePack.Info.ActivePlayCard.Pos - 1]++;
|
||||
if (Rule.BiYa && GamePack.Info.MaxPlayCard.Type == CardType1.ZhaDan)
|
||||
{
|
||||
//把之前加的炸弹减回去。
|
||||
//GamePack.Info.ZhaDans[GamePack.Info.MaxPlayCard.Pos - 1]--;
|
||||
AddZhaDanCount(GamePack.Info.MaxPlayCard.Pos, -1);
|
||||
}
|
||||
}
|
||||
GamePack.Info.MaxPlayCard = GamePack.Info.ActivePlayCard;
|
||||
}
|
||||
if (IsGameOver(chupaiPos))
|
||||
{ //游戏是否结束
|
||||
SendPack();
|
||||
this.TimeNum = 0;
|
||||
GamePack.Info.GameZT = 5;
|
||||
// GameOver(); 修改为定时器驱动
|
||||
return;
|
||||
}
|
||||
GamePack.Info.WhoPlay = GetNextPos(GamePack.Info.WhoPlay);
|
||||
Debug.Info($"当前玩家:{GamePack.Info.WhoPlay},下一个出牌的人:{GamePack.Info.WhoPlay}");
|
||||
if (GamePack.Info.WhoPlay == GamePack.Info.MaxPlayCard.Pos)
|
||||
{ //一轮结束
|
||||
Log("一轮结束");
|
||||
GamePack.Info.MaxPlayCard.Pos = 0;
|
||||
GamePack.Info.MaxPlayCard.GameNum = 0;
|
||||
GamePack.Info.MaxPlayCard.Type = CardType1.None;
|
||||
GamePack.Info.MaxPlayCard.Ids = null;
|
||||
}
|
||||
SendPack();
|
||||
}
|
||||
|
||||
void GameOver()
|
||||
{
|
||||
Log($"进入结算 bao:{GamePack.Info.BaoPos},overpos:{GamePack.Info.OverPos}");
|
||||
int count = 0;
|
||||
if (Rule.JingDianWanFa || Rule.GuanPai)
|
||||
{
|
||||
count = 16;
|
||||
}
|
||||
if (Rule.Zhang15)
|
||||
{
|
||||
count = 15;
|
||||
}
|
||||
|
||||
if (GamePack.Info.BaoPos > 0)
|
||||
{ //有人包庄
|
||||
var baoWin = GamePack.Info.BaoPos == GamePack.Info.OverPos;
|
||||
Log($"baowin:{baoWin}");
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (i + 1 != GamePack.Info.BaoPos)
|
||||
{ //先统计闲家
|
||||
int bei = GamePack.Info.HongTaoShiPos == i + 1 || GamePack.Info.HongTaoShiPos == GamePack.Info.BaoPos ? 4 : 2; //红桃十扎鸟
|
||||
GamePack.Info.Score[i] += (baoWin ? 0 - count * bei : count * bei);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{//先统计闲家
|
||||
if (i + 1 != GamePack.Info.OverPos)
|
||||
{
|
||||
if (GamePack.Info.ShenYuCard[i] == 1) continue;
|
||||
var bei = GamePack.Info.HongTaoShiPos == i + 1 || GamePack.Info.HongTaoShiPos == GamePack.Info.OverPos ? 2 : 1;//红桃十扎鸟
|
||||
var num = GamePack.Info.ShenYuCard[i] == count ? count * 2 : GamePack.Info.ShenYuCard[i];
|
||||
GamePack.Info.Score[i] += 0 - num * bei;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (i + 1 == (GamePack.Info.BaoPos > 0 ? GamePack.Info.BaoPos : GamePack.Info.OverPos))
|
||||
{ //统计庄家,把闲家的都加起来就是庄家的输赢
|
||||
for (int j = 0; j < GamePack.Info.PlayNum; j++)
|
||||
{
|
||||
if (j == i) continue;
|
||||
GamePack.Info.Score[i] -= GamePack.Info.Score[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (GamePack.Info.ZhaDans[i] != 0)
|
||||
{
|
||||
GamePack.Info.Score[i] += (GamePack.Info.ZhaDans[i] * 10);
|
||||
}
|
||||
}
|
||||
//处理托管罚分
|
||||
var fafen = GetTuoGuanFaFen();
|
||||
if (fafen > 0)
|
||||
{
|
||||
var tgPos = GetTuoGuanPlay();
|
||||
if (tgPos >= 0)
|
||||
{ //有玩家托管
|
||||
//int fen = fafen / (GamePack.Info.PlayNum - 1);
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (i == tgPos)
|
||||
{
|
||||
GamePack.Info.Score[i] -= (fafen * (GamePack.Info.PlayNum - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
GamePack.Info.Score[i] += fafen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
Log($"玩家:{(i + 1)} ,输赢:{GamePack.Info.Score[i]}");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (DeskGameDo != null)
|
||||
{
|
||||
DeskGameDo.GameOver();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否托管罚分
|
||||
/// </summary>
|
||||
/// <returns>0不罚分 </returns>
|
||||
int GetTuoGuanFaFen()
|
||||
{
|
||||
if (this.DeskGameDo == null || this.DeskGameDo.desk == null || this.DeskGameDo.desk.deskinfo == null || this.DeskGameDo.desk.deskinfo.rule == null ||
|
||||
this.DeskGameDo.desk.deskinfo.rule.RuleEx == null) return 0;
|
||||
return this.DeskGameDo.desk.deskinfo.rule.RuleEx.DepositAutoDissolve ? this.DeskGameDo.desk.deskinfo.rule.RuleEx.OutLinePenaltyPoint : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 找打托管的玩家
|
||||
/// </summary>
|
||||
/// <returns>从0开始 -1未找到</returns>
|
||||
int GetTuoGuanPlay()
|
||||
{
|
||||
return DeskGameDo.GetPlayerFirstDepositSeat();
|
||||
//var desk = DeskGameDo.GetDesk();
|
||||
//for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
//{
|
||||
// if (desk[i] != null && desk[i].isDePosit)
|
||||
// {//找到在 托管的玩家
|
||||
// return i;
|
||||
// }
|
||||
//}
|
||||
//return -1;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 游戏发包,发全包
|
||||
/// </summary>
|
||||
void SendPack()
|
||||
{
|
||||
Log($"whoPlay:{GamePack.Info.WhoPlay}");
|
||||
if (DeskGameDo == null)
|
||||
{
|
||||
var str = JsonPack.GetJson(this.GamePack);
|
||||
File.WriteAllText(@"C:\Users\Administrator\Desktop\temp\gamepack.txt", str);
|
||||
var path = $@"C:\Users\Administrator\Desktop\temp\test\gamepack{DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff")}.txt";
|
||||
Log("保存文件:" + path);
|
||||
File.WriteAllText(path, str);
|
||||
WaitWanJiaShuRu(); //等玩家输入。模拟玩家打牌
|
||||
}
|
||||
else
|
||||
{
|
||||
SetOperation();
|
||||
DeskGameDo.SendGamePack();
|
||||
}
|
||||
}
|
||||
|
||||
void SetFalseOperation()
|
||||
{
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
this.SetWaitOperation(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetOperation()
|
||||
{
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
|
||||
var pl = this.DeskGameDo.desk[i];
|
||||
if (pl != null)
|
||||
{
|
||||
GamePack.Info.PlayTuoGauan[i] = (byte)(pl.isDePosit ? 1 : 0);
|
||||
}
|
||||
bool b = false; //包庄流程是同时进行的
|
||||
if (GamePack.Info.GameZT == 3)
|
||||
{
|
||||
b = GamePack.Info.BaoZhuang[i] == 0;
|
||||
}
|
||||
this.SetWaitOperation(i, GamePack.Info.GameZT == 3 ? b : i + 1 == GamePack.Info.WhoPlay);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置玩家的操作权
|
||||
/// </summary>
|
||||
/// <param name="seat">下标从0开始</param>
|
||||
/// <param name="waitOperation"></param>
|
||||
public void SetWaitOperation(int seat, bool waitOperation)
|
||||
{
|
||||
var desk = this.DeskGameDo.GetDesk();
|
||||
if (seat < 0 || seat >= desk.PlayerCnt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pl = desk[seat];
|
||||
if (pl != null)
|
||||
{
|
||||
//之前不能操作,现在可以操作,重置托管时间
|
||||
if (!pl.WaitOperation && waitOperation)
|
||||
{
|
||||
pl.AutoDepositTime = 0;
|
||||
}
|
||||
pl.WaitOperation = waitOperation;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查包内容是否合法
|
||||
/// </summary>
|
||||
/// <param name="pack"></param>
|
||||
/// <returns></returns>
|
||||
public bool CheckPack(PdkLogicInfo pack)
|
||||
{
|
||||
if (pack.WhoPlay != GamePack.Info.WhoPlay && GamePack.Info.GameZT > 3) return false;
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
case 3: //包庄 只能输入1和2
|
||||
return pack.BaoZhuang[pack.WhoPlay - 1] == 1 || pack.BaoZhuang[pack.WhoPlay - 1] == 2;
|
||||
case 4:
|
||||
if (pack.WhoPlay != pack.ActivePlayCard.Pos)
|
||||
{
|
||||
Debug.Error($"who:{pack.WhoPlay},apos:{pack.ActivePlayCard}");
|
||||
return false;
|
||||
}
|
||||
return CheckChuPai(pack.ActivePlayCard);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GameDo()
|
||||
{
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
//case 1:
|
||||
// GameStart();
|
||||
// break;
|
||||
case 2:
|
||||
GameFaPai();
|
||||
break;
|
||||
case 3:
|
||||
GameBaoZhuang();
|
||||
break;
|
||||
case 4:
|
||||
GameDaPai();
|
||||
break;
|
||||
case 5:
|
||||
GameOver();
|
||||
break;
|
||||
default:
|
||||
Log("default GameDo game over!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等待玩家输入
|
||||
/// </summary>
|
||||
void WaitWanJiaShuRu()
|
||||
{
|
||||
if (DeskGameDo != null) return;
|
||||
//正式连客户端以后要屏蔽这些代码。return
|
||||
string str = "";
|
||||
byte num = 0;
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
case 3://包庄流程,只能输入1和2
|
||||
Log("包庄操作 pos:" + GamePack.Info.WhoPlay);
|
||||
while (true)
|
||||
{
|
||||
str = Console.ReadLine();
|
||||
Log(str);
|
||||
var ss = str.Split(',');
|
||||
byte.TryParse(ss[0], out var pos);
|
||||
byte.TryParse(ss[1], out num);
|
||||
GamePack.Info.WhoPlay = pos;
|
||||
GamePack.Info.BaoZhuang[pos - 1] = num;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4: //打牌流程
|
||||
Log("打牌操作 pos:" + GamePack.Info.WhoPlay);
|
||||
while (true)
|
||||
{
|
||||
str = Console.ReadLine(); //逗号分隔
|
||||
var ss = str.Split(',');
|
||||
if (ss.Length <= 0) continue;
|
||||
Log(str);
|
||||
var selectCards = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => ss.Any(s => s == x.ID.ToString())).ToArray();
|
||||
PlayOutCardPdkF payCard;
|
||||
if (selectCards == null || selectCards.Length <= 0) //不要
|
||||
{
|
||||
payCard = new PlayOutCardPdkF();
|
||||
payCard.Pos = GamePack.Info.WhoPlay;
|
||||
payCard.Type = CardType1.None;
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
|
||||
}
|
||||
else if (PdkCardAlgorithm.GetOutCard(selectCards,
|
||||
GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
|
||||
this.Rule, out payCard))
|
||||
{
|
||||
payCard.Pos = GamePack.Info.WhoPlay;
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
if (CheckPack(GamePack.Info))
|
||||
{
|
||||
break; //如果包输入正确就跳走
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("检测不合格,输入非法值");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("输入的牌不符合规则,不能出下去");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
//GameOver();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void textxxxx()
|
||||
{
|
||||
|
||||
// GameStart();
|
||||
// GameFaPai();
|
||||
//PlayOutCard output = new PlayOutCard();
|
||||
//output.Pos = 1; output.Type = CardType.LianDui;
|
||||
//output.GameNum = 9;
|
||||
//output.Ids = new byte[6];
|
||||
//TCardInfo[] shoupai = new TCardInfo[16];
|
||||
//shoupai[0] = new TCardInfo() { ID = 1, GameNum = 14, Flower = 1, Num = 14, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[1] = new TCardInfo() { ID = 27, GameNum = 14, Flower = 3, Num = 14, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[2] = new TCardInfo() { ID = 26, GameNum = 13, Flower = 2, Num = 13, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[3] = new TCardInfo() { ID = 25, GameNum = 12, Flower = 2, Num = 12, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[4] = new TCardInfo() { ID = 38, GameNum = 12, Flower = 3, Num = 12, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[5] = new TCardInfo() { ID = 36, GameNum = 10, Flower = 3, Num = 10, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[6] = new TCardInfo() { ID = 49, GameNum = 10, Flower = 4, Num = 10, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[7] = new TCardInfo() { ID = 35, GameNum = 9, Flower = 3, Num = 9, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[8] = new TCardInfo() { ID = 48, GameNum = 9, Flower = 4, Num = 9, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[9] = new TCardInfo() { ID = 8, GameNum = 8, Flower = 1, Num = 8, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[10] = new TCardInfo() { ID = 34, GameNum = 8, Flower = 3, Num = 8, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[11] = new TCardInfo() { ID = 5, GameNum = 5, Flower = 1, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[12] = new TCardInfo() { ID = 18, GameNum = 5, Flower = 2, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[13] = new TCardInfo() { ID = 44, GameNum = 5, Flower = 4, Num = 5, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[14] = new TCardInfo() { ID = 16, GameNum = 3, Flower =2, Num = 3, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//shoupai[15] = new TCardInfo() { ID = 29, GameNum = 3, Flower = 3, Num = 3, Score = 0, GameOwer = 1, GameState = 1 };
|
||||
//var tishi = PdkCardAlgorithm.GetTipCard(output, shoupai, null);
|
||||
//Console.WriteLine(tishi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试函数
|
||||
/// </summary>
|
||||
public void Test(string path = "")
|
||||
{
|
||||
//textxxxx();
|
||||
//return;
|
||||
if (File.Exists("output.txt"))
|
||||
{
|
||||
File.Delete("output.txt");
|
||||
}
|
||||
foreach (string file in Directory.GetFiles(@"C:\Users\Administrator\Desktop\temp\test"))
|
||||
{
|
||||
File.Delete(file);
|
||||
}
|
||||
bool b = true;
|
||||
GamePack.Info.GameZT = 1;
|
||||
if (!string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
GamePack = JsonPack.GetData<PdkGamePack>(File.ReadAllText(path));
|
||||
}
|
||||
while (b)
|
||||
{
|
||||
switch (GamePack.Info.GameZT)
|
||||
{
|
||||
case 1:
|
||||
GameStart();
|
||||
break;
|
||||
case 2:
|
||||
GameFaPai();
|
||||
break;
|
||||
case 3:
|
||||
GameBaoZhuang();
|
||||
break;
|
||||
case 4:
|
||||
GameDaPai();
|
||||
break;
|
||||
case 5:
|
||||
GameOver();
|
||||
GamePack.Info.GameZT = 11; //进入结束就结束
|
||||
break;
|
||||
default:
|
||||
b = false;
|
||||
Log("test over!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void WriteToConsoleAndFile(StreamWriter writer, string message)
|
||||
{
|
||||
Console.WriteLine(message); // 写入控制台
|
||||
writer.WriteLine(message); // 写入文件
|
||||
}
|
||||
|
||||
public void Log(string msg, DebugLevel leve = DebugLevel.Info)
|
||||
{
|
||||
if (DeskGameDo == null)
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter("output.txt", true)) // 第二个参数为true表示追加到文件
|
||||
{
|
||||
WriteToConsoleAndFile(writer, $"[{DateTime.Now.ToString("G")}]:" + msg);
|
||||
}
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (leve)
|
||||
{
|
||||
case DebugLevel.Info:
|
||||
Debug.Info(msg);
|
||||
break;
|
||||
case DebugLevel.Warning:
|
||||
Debug.Warning(msg);
|
||||
break;
|
||||
case DebugLevel.ImportantLog:
|
||||
Debug.ImportantLog(msg);
|
||||
break;
|
||||
case DebugLevel.Error:
|
||||
Debug.Error(msg);
|
||||
break;
|
||||
case DebugLevel.Fatal:
|
||||
Debug.Fatal(msg);
|
||||
break;
|
||||
default:
|
||||
Debug.Info(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
348
PdkFriendServer/Logic/PdkGameMain_Card.cs
Normal file
348
PdkFriendServer/Logic/PdkGameMain_Card.cs
Normal file
@ -0,0 +1,348 @@
|
||||
using ObjectModel.Tool;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GameFix.Poker;
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
using GameFix.PaoDeKuaiF;
|
||||
|
||||
namespace PdkFriendServer.Logic
|
||||
{
|
||||
|
||||
public partial class PdkGameMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 随机值
|
||||
/// </summary>
|
||||
public readonly Random Random = new Random(unchecked((int)DateTime.UtcNow.Ticks));
|
||||
|
||||
/// <summary>
|
||||
/// 发牌
|
||||
/// </summary>
|
||||
public void InitCard()
|
||||
{
|
||||
/*1、经典玩法(必压)、--经典玩法(16张玩法):一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张
|
||||
15张玩法(必压)、--15张玩法(有大必压):一副牌,去掉大小王、三个2(保留黑桃2)和三个A(保留黑桃 A ),去掉一个K,共45张,每人15张
|
||||
关牌(不必压) --一副牌,去掉大小王、三个2(保留黑桃2)和黑桃 A ,共48张,每人16张*/
|
||||
byte count = 0;//每个人分多少张牌
|
||||
int del2 = 3; //删除2的张数
|
||||
int delA = 1;//删除A的张数
|
||||
int delK = 3;//删除K的张数
|
||||
TCardInfoPdkF[] allCards = null; //初始化牌库
|
||||
if (Rule.JingDianWanFa || Rule.GuanPai)
|
||||
{
|
||||
count = 16;
|
||||
delK = 0;
|
||||
allCards = new TCardInfoPdkF[48];
|
||||
}
|
||||
if (Rule.Zhang15)
|
||||
{
|
||||
delA = 3;
|
||||
delK = 1;
|
||||
count = 15;
|
||||
allCards = new TCardInfoPdkF[45];
|
||||
}
|
||||
int idx = 0;
|
||||
for (byte i = 1; i <= 52; i++)
|
||||
{
|
||||
PukeTool.ConvertCard(i, out var flower, out var num);
|
||||
if (del2 > 0 && num == 2 && flower != 1)
|
||||
{
|
||||
del2--;
|
||||
continue;
|
||||
}
|
||||
if (delA > 0 && num == 1 && flower != 1)
|
||||
{
|
||||
delA--;
|
||||
continue;
|
||||
}
|
||||
if (delK > 0 && num == 13 && flower != 1)
|
||||
{
|
||||
delK--;
|
||||
continue;
|
||||
}
|
||||
allCards[idx].ID = i;
|
||||
allCards[idx].Flower = (byte)flower;
|
||||
allCards[idx].Num = (byte)num;
|
||||
allCards[idx].GameNum = (byte)(num == 1 ? 14 : num == 2 ? 16 : num);
|
||||
allCards[idx].GameOwer = 0;
|
||||
allCards[idx].Score = 0;
|
||||
allCards[idx].GameState = 1;
|
||||
idx++;
|
||||
}
|
||||
for (byte i = 1; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
PukeTool.ShuffleArray(ref allCards, Random);
|
||||
}
|
||||
idx = 0;
|
||||
//给玩家发牌
|
||||
int hei3Wei = -1;//黑桃三发牌的位置
|
||||
if (logicMemory.WarCount == 0 && Rule.HeiTao3BiChu)
|
||||
{//如果是首局而且是每局黑桃三必出,则第一局必须要发黑桃三
|
||||
hei3Wei = Random.Next(0, GamePack.Info.PlayNum);
|
||||
}
|
||||
if (hei3Wei >= 0)
|
||||
{ //要发黑桃3
|
||||
List<TCardInfoPdkF> cards = allCards.ToList();
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
GamePack.CardPack.Cards[i].Init(count);
|
||||
int j = 0;
|
||||
while (j < count)
|
||||
{
|
||||
if (j == 0 && i == hei3Wei)
|
||||
{
|
||||
TCardInfoPdkF temp = cards.Find(x => x.GameNum == 3 && x.Flower == 1);
|
||||
if (temp.ID > 0)
|
||||
{
|
||||
this.GamePack.CardPack.Cards[i].CardInfos[j] = temp;
|
||||
cards.Remove(temp);
|
||||
}
|
||||
else
|
||||
{ //如果没有找到,说明黑桃3已经被别人拿走了,就不找了。
|
||||
this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
|
||||
cards.RemoveAt(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.GamePack.CardPack.Cards[i].CardInfos[j] = cards[0];
|
||||
cards.RemoveAt(0);
|
||||
}
|
||||
j++;
|
||||
}
|
||||
GamePack.Info.ShenYuCard[i] = count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //以前写法
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
GamePack.CardPack.Cards[i].Init(count);
|
||||
for (int j = 0; j < count; j++)
|
||||
{
|
||||
this.GamePack.CardPack.Cards[i].CardInfos[j] = allCards[idx++];
|
||||
}
|
||||
GamePack.Info.ShenYuCard[i] = count;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
SortWanJiaPaiByGameNum(i + 1);
|
||||
#if DEBUG
|
||||
if (this.DeskGameDo == null)
|
||||
{
|
||||
Log($"-------------{(i + 1)}开始-----------------------------");
|
||||
for (int j = 0; j < this.GamePack.CardPack.Cards[i].CardInfos.Length; j++)
|
||||
{
|
||||
Log(this.GamePack.CardPack.Cards[i].CardInfos[j].ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 排序某个玩家手牌,按游戏中的大小排序
|
||||
/// </summary>
|
||||
/// <param name="pos">玩家位置从1开始</param>
|
||||
void SortWanJiaPaiByGameNum(int pos)
|
||||
{
|
||||
if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
|
||||
pos--;
|
||||
Array.Sort(this.GamePack.CardPack.Cards[pos].CardInfos, (x, y) => (y.GameNum * 10 - y.Flower).CompareTo((x.GameNum * 10 - x.Flower)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置玩家出牌
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="ids"></param>
|
||||
void SetCardToOut(int pos, byte[] ids)
|
||||
{
|
||||
if (ids == null || ids.Length <= 0) return;
|
||||
if (pos <= 0 || pos > GamePack.Info.PlayNum) throw new Exception($"参数错误 pos:{pos}");
|
||||
pos--;
|
||||
GamePack.Info.ShenYuCard[pos] = (byte)(GamePack.Info.ShenYuCard[pos] - ids.Length);
|
||||
foreach (var id in ids)
|
||||
{
|
||||
for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
|
||||
{
|
||||
if (this.GamePack.CardPack.Cards[pos].CardInfos[i].ID == id)
|
||||
{
|
||||
this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
Log($"---------------------{(pos + 1)}----- shengyu:{GamePack.Info.ShenYuCard[pos]}-------------");
|
||||
//for (int i = 0; i < this.GamePack.CardPack.Cards[pos].CardInfos.Length; i++)
|
||||
//{
|
||||
// if (this.GamePack.CardPack.Cards[pos].CardInfos[i].GameState == 0) continue;
|
||||
// Log(this.GamePack.CardPack.Cards[pos].CardInfos[i].ToString());
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据牌的绝对Id返回牌的详细信息
|
||||
/// </summary>
|
||||
/// <param name="pos">玩家位置从1开始</param>
|
||||
/// <param name="ids">牌的Id集合</param>
|
||||
/// <returns></returns>
|
||||
TCardInfoPdkF[] GetCardByIds(int pos, byte[] ids)
|
||||
{
|
||||
if (ids == null || ids.Length <= 0) return null;
|
||||
if (pos <= 0 || pos > GamePack.Info.PlayNum) return null;
|
||||
pos--;
|
||||
return PokerLogic.GetCardByIds(GamePack.CardPack.Cards[pos].CardInfos, ids);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算玩家炸弹个数
|
||||
/// </summary>
|
||||
/// <param name="pos">玩家位置,从0开始</param>
|
||||
/// <returns></returns>
|
||||
byte CalcPlayBombRule(int pos)
|
||||
{
|
||||
if (pos < 0 || pos >= GamePack.Info.PlayNum) return 0;
|
||||
Dictionary<int, int> dic = new Dictionary<int, int>();
|
||||
foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
|
||||
{
|
||||
if (dic.ContainsKey(item.GameNum))
|
||||
{
|
||||
dic[item.GameNum]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
dic[item.GameNum] = 1;
|
||||
}
|
||||
}
|
||||
byte result = 0;
|
||||
foreach (var item in dic)
|
||||
{
|
||||
if (item.Value <= 2) continue;
|
||||
if (Rule.AAAIsZhaDan && item.Key == 14 && item.Value == 3)
|
||||
{
|
||||
result++;
|
||||
continue;
|
||||
}
|
||||
if (item.Value == 4)
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测玩家的飞机,如果有4连以上的飞机就需要换牌
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <returns></returns>
|
||||
void CheckFeiJi()
|
||||
{
|
||||
try
|
||||
{
|
||||
int pos = -1; //有4连飞机的位置
|
||||
List<int> feiji = null;
|
||||
for (int j = 0; j < GamePack.Info.PlayNum; j++)
|
||||
{
|
||||
feiji = GetFeiJiCount(GamePack.CardPack.Cards[j].CardInfos);
|
||||
if (feiji != null && feiji.Count > 3)
|
||||
{
|
||||
pos = j;
|
||||
Log($"飞机数量:{string.Join(",", feiji)},飞机位置:{pos + 1},房号:{this.DeskGameDo.desk.deskinfo.roomNum}", MrWu.Debug.DebugLevel.Warning);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pos < 0) return;
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (i != pos)
|
||||
{
|
||||
int idx = -1;
|
||||
for (int j = 0; j < GamePack.CardPack.Cards[pos].CardInfos.Length; j++)
|
||||
{
|
||||
if (GamePack.CardPack.Cards[pos].CardInfos[j].GameNum == feiji[2])
|
||||
{
|
||||
idx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx < 0)
|
||||
{
|
||||
Log($"没有找到4连飞机的下标日:{idx}", MrWu.Debug.DebugLevel.Warning);
|
||||
return;
|
||||
}
|
||||
for (int i3 = 0; i3 < GamePack.CardPack.Cards[i].CardInfos.Length - 1; i3++)
|
||||
{
|
||||
//交换其中一张牌
|
||||
TCardInfoPdkF temp = GamePack.CardPack.Cards[i].CardInfos[i3];
|
||||
if (feiji.IndexOf(temp.GameNum) >= 0) continue; //换的牌不能是飞机的牌,要不容易重复和换出新的炸弹
|
||||
Log($"换牌信息:{temp.GameNum}", MrWu.Debug.DebugLevel.Warning);
|
||||
GamePack.CardPack.Cards[i].CardInfos[i3] = GamePack.CardPack.Cards[pos].CardInfos[idx];
|
||||
GamePack.CardPack.Cards[pos].CardInfos[idx] = temp;
|
||||
for (int i2 = 0; i2 < GamePack.Info.PlayNum; i2++)
|
||||
{
|
||||
SortWanJiaPaiByGameNum(i2 + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log($"CheckFeiJi msg:{e.Message}, code:{e.StackTrace}", MrWu.Debug.DebugLevel.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个玩家的飞机牌型
|
||||
/// </summary>
|
||||
/// <param name="selectCards">玩家手里的牌</param>
|
||||
/// <returns>玩家的飞机集合</returns>
|
||||
public static List<int> GetFeiJiCount(TCardInfoPdkF[] selectCards)
|
||||
{
|
||||
if (selectCards == null || selectCards.Length < 6) return null;
|
||||
List<PokerLogic.XY> list = new List<PokerLogic.XY>();
|
||||
foreach (var item in selectCards)
|
||||
{
|
||||
var t = list.Find(x => x.x == item.GameNum);
|
||||
if (t != null)
|
||||
{
|
||||
t.y++;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(new PokerLogic.XY { x = item.GameNum, y = 1 });
|
||||
}
|
||||
}
|
||||
int num = list.Count(x => x.y >= 3);
|
||||
if (num < 2) return null;
|
||||
list = list.Where(x => x.y >= 3).ToList();
|
||||
List<int> fj = new List<int>();
|
||||
for (int i = 0; i < list.Count - 1; i++)
|
||||
{
|
||||
if (list[i].x - 1 == list[i + 1].x)
|
||||
{
|
||||
if (!fj.Contains(list[i].x))
|
||||
{
|
||||
fj.Add(list[i].x);
|
||||
}
|
||||
if (!fj.Contains(list[i + 1].x))
|
||||
{
|
||||
fj.Add(list[i + 1].x);
|
||||
}
|
||||
}
|
||||
}
|
||||
return fj;
|
||||
}
|
||||
}
|
||||
}
|
||||
468
PdkFriendServer/Logic/PdkGameMain_Method.cs
Normal file
468
PdkFriendServer/Logic/PdkGameMain_Method.cs
Normal file
@ -0,0 +1,468 @@
|
||||
using GameData;
|
||||
using MrWu.Debug;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GameFix.Poker;
|
||||
using GameFix.PaoDeKuaiF;
|
||||
using GameMessage;
|
||||
using GameMessage.PaoDeKuaiF;
|
||||
|
||||
namespace PdkFriendServer.Logic
|
||||
{
|
||||
public partial class PdkGameMain
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取黑桃3的位置,如果都没有黑桃3那就取黑桃4
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
byte GetHeiTao3Pos()
|
||||
{
|
||||
byte result = 0;
|
||||
for (byte carId = 3; carId < 14; carId++)
|
||||
{//从黑桃3开始找,没有找到就依次往上查找
|
||||
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
|
||||
{
|
||||
if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 1) continue;
|
||||
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum > carId) break;
|
||||
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == carId)
|
||||
{
|
||||
result = (byte)(i + 1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取红桃十的玩家位置
|
||||
/// </summary>
|
||||
/// <returns>0没有玩家有红桃十 大于0就是改位置的玩家</returns>
|
||||
byte GetHongTaoShiPos()
|
||||
{
|
||||
byte result = 0;
|
||||
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
for (int j = GamePack.CardPack.Cards[i].CardInfos.Length - 1; j >= 0; j--)
|
||||
{
|
||||
if (GamePack.CardPack.Cards[i].CardInfos[j].Flower != 2) continue;
|
||||
if (GamePack.CardPack.Cards[i].CardInfos[j].GameNum == 10)
|
||||
{
|
||||
result = (byte)(i + 1);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找下一个玩家的位置
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <returns></returns>
|
||||
byte GetNextPos(byte pos)
|
||||
{
|
||||
if (pos <= 0) throw new Exception("参数错误" + pos);
|
||||
byte result = (byte)(pos + 1);
|
||||
if (result > GamePack.Info.PlayNum)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏是否结束
|
||||
/// </summary>
|
||||
/// <returns>true游戏结束 false游戏没有结束</returns>
|
||||
bool IsGameOver(byte chupaoPos)
|
||||
{
|
||||
if (GamePack.Info.BaoPos > 0 && GamePack.Info.ShenYuCard[GamePack.Info.BaoPos - 1] == 0)
|
||||
{
|
||||
//包庄人的牌出完了,游戏结束
|
||||
GamePack.Info.OverPos = GamePack.Info.BaoPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
//如果是包庄的话,出牌的人
|
||||
if (GamePack.Info.BaoPos > 0 && chupaoPos > 0)
|
||||
{
|
||||
var b = GamePack.Info.BaoPos != chupaoPos; //如果出牌的位置和包庄位置不一样。就说明被别人给压牌了,游戏结束
|
||||
if (b)
|
||||
{
|
||||
GamePack.Info.OverPos = chupaoPos; //记录压他牌的人位置
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
if (GamePack.Info.ShenYuCard[i] <= 0)
|
||||
{ //只要有一个玩家的牌出完就结束
|
||||
GamePack.Info.OverPos = (byte)(i + 1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查出牌包内容
|
||||
/// </summary>
|
||||
/// <param name="pack"></param>
|
||||
/// <returns></returns>
|
||||
public bool CheckChuPai(PlayOutCardPdkF payCard)
|
||||
{
|
||||
if (payCard.Pos <= 0 || payCard.Pos > 3) return false;
|
||||
if (PokerLogic.CheckSameId(payCard.Ids))
|
||||
{
|
||||
Log($"玩家出了相同ID的牌型,{payCard}", DebugLevel.Error);
|
||||
return false;
|
||||
}
|
||||
if (GamePack.Info.MaxPlayCard.GameNum == 0 && payCard.Type == CardType1.None) return false; //第一个出牌人不能出不要
|
||||
if (GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType1.None)
|
||||
{
|
||||
if (!Rule.BiYa && !Rule.XiaJiaBaoDan) return true; //不是必压的情况下,并且没有勾选下家报单,之前有人出牌,再出个不要可以出
|
||||
//不必压,但是勾选下家报单,之前出的不是单张,这个时候可以出不要。
|
||||
if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type != CardType1.DanZhang) return true;
|
||||
if (!Rule.BiYa && Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] != 1) return true;
|
||||
}
|
||||
if (!CheckPaiIsInHand(payCard.Ids, payCard.Pos)) return false;
|
||||
if (!Rule.AAAIsZhaDan && payCard.Type == CardType1.ZhaDan && payCard.GameNum == 14) return false; //3个A不是炸弹
|
||||
if (!Rule.SiDai2 && payCard.Type == CardType1.SiDai2) return false;
|
||||
if (!Rule.SiDai3 && payCard.Type == CardType1.SiDai3) return false;
|
||||
//if (!Rule.BiYa && GamePack.Info.MaxPlayCard.GameNum > 0 && payCard.Type == CardType.None) return true; //如果之前有人出牌,再出个不要可以出
|
||||
if ((Rule.BiYa ||
|
||||
(Rule.XiaJiaBaoDan && GamePack.Info.MaxPlayCard.Type == CardType1.DanZhang && GamePack.Info.ShenYuCard[GetNextPos(payCard.Pos) - 1] == 1))
|
||||
&& payCard.Type == CardType1.None)
|
||||
{ //如果是必压,玩家出了不要,检查一下玩家有没有必上一家大的牌
|
||||
return !PdkCardAlgorithm.CheckHaveBigger(GamePack.Info.MaxPlayCard, GamePack.CardPack.Cards[payCard.Pos - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
|
||||
GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos, Rule.AAAIsZhaDan);
|
||||
}
|
||||
int count = GamePack.Info.ShenYuCard[payCard.Pos - 1];
|
||||
//单张、对子、三带二、顺子、连对、飞机带翅膀、炸弹,四带三、四带二
|
||||
if (payCard.Type == CardType1.SanDai2 && count >= 5 && payCard.Ids.Length < 5) return false;
|
||||
if (payCard.Type == CardType1.SiDai3 && count >= 7 && payCard.Ids.Length < 7) return false;
|
||||
if (payCard.Type == CardType1.SiDai2 && count >= 6 && payCard.Ids.Length < 6) return false;
|
||||
if (payCard.Type == CardType1.FeiJi)
|
||||
{//如果飞机的张数不够就返回false
|
||||
if (count >= 10 && payCard.Ids.Length < 10) return false;
|
||||
var sanzhang = PokerLogic.GetFeiJiCount(GetCardByIds(payCard.Pos, payCard.Ids));
|
||||
var c = sanzhang * 3 + sanzhang * 2;
|
||||
if (count >= c && payCard.Ids.Length < c) return false;
|
||||
var maxSanZahng = PokerLogic.GetFeiJiCount(GetCardByIds(GamePack.Info.MaxPlayCard.Pos, GamePack.Info.MaxPlayCard.Ids));
|
||||
if (sanzhang < maxSanZahng) return false;
|
||||
}
|
||||
if (GamePack.Info.MaxPlayCard.GameNum == 0)
|
||||
{
|
||||
//如果最大的出牌人是没有值的话,然后当前人不是出不要就可以出下去。
|
||||
return payCard.Type != CardType1.None;
|
||||
}
|
||||
if (GamePack.Info.MaxPlayCard.Type == payCard.Type)
|
||||
{
|
||||
if (payCard.Type == CardType1.DanZhang || payCard.Type == CardType1.DuiZi || payCard.Type == CardType1.ShunZi || payCard.Type == CardType1.LianDui)
|
||||
{
|
||||
return payCard.Ids.Length == GamePack.Info.MaxPlayCard.Ids.Length && payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
|
||||
}
|
||||
else
|
||||
{
|
||||
return payCard.GameNum > GamePack.Info.MaxPlayCard.GameNum;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GamePack.Info.MaxPlayCard.Type != CardType1.ZhaDan)
|
||||
{
|
||||
return payCard.Type == CardType1.ZhaDan;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测牌是否都在玩家手上
|
||||
/// </summary>
|
||||
/// <param name="Ids">要检测的牌ID集合</param>
|
||||
/// <param name="pos">要检测哪个玩家的手牌</param>
|
||||
/// <returns>true都在手上 false没有在手上</returns>
|
||||
bool CheckPaiIsInHand(byte[] Ids, int pos)
|
||||
{
|
||||
if (pos <= 0 || pos > GamePack.Info.PlayNum) return false;
|
||||
if (Ids == null || Ids.Length <= 0) return true; //没有牌不检测
|
||||
pos--;
|
||||
int count = 0;
|
||||
foreach (var id in Ids)
|
||||
{
|
||||
foreach (var item in GamePack.CardPack.Cards[pos].CardInfos)
|
||||
{
|
||||
if (item.ID == id && item.GameState == 1)
|
||||
{
|
||||
count++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count == Ids.Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 给某个玩家加炸弹,其他玩家减炸弹
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="num"></param>
|
||||
void AddZhaDanCount(int pos, int num)
|
||||
{
|
||||
for (int i = 0; i < GamePack.Info.ZhaDans.Length; i++)
|
||||
{
|
||||
if (i + 1 == pos)
|
||||
{
|
||||
GamePack.Info.ZhaDans[i] += num * (GamePack.Info.ZhaDans.Length - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GamePack.Info.ZhaDans[i] -= num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置朋友房规则
|
||||
/// </summary>
|
||||
public void SetFriendGz()
|
||||
{
|
||||
if (this.DeskGameDo == null) return;
|
||||
var gz = this.DeskGameDo.GetRoomGz();
|
||||
Rule = new PdkRule();
|
||||
Rule.BiYa = true;//不必压
|
||||
if (gz[0] == '0')
|
||||
{
|
||||
Rule.JingDianWanFa = true;
|
||||
}
|
||||
else if (gz[0] == '1')
|
||||
{
|
||||
Rule.Zhang15 = true;
|
||||
}
|
||||
else if (gz[0] == '2')
|
||||
{
|
||||
Rule.GuanPai = true;
|
||||
Rule.BiYa = false;//不必压
|
||||
}
|
||||
if (gz[1] == '0')
|
||||
{
|
||||
Rule.ShouJu3 = true;
|
||||
}
|
||||
else if (gz[1] == '1')
|
||||
{
|
||||
Rule.MeiJu3 = true;
|
||||
}
|
||||
if (gz[2] == '0')
|
||||
{
|
||||
Rule.SiDai3 = true;
|
||||
}
|
||||
else if (gz[2] == '1')
|
||||
{
|
||||
Rule.SiDai2 = true;
|
||||
}
|
||||
if (gz[8] == '0')
|
||||
{
|
||||
GamePack.Info.PlayNum = 2;
|
||||
}
|
||||
else if (gz[8] == '1')
|
||||
{
|
||||
GamePack.Info.PlayNum = 3;
|
||||
}
|
||||
Rule.XianShenYuPai = gz[3] == '1';
|
||||
Rule.HongTao10ZhaNiao = gz[4] == '1';
|
||||
Rule.BaoZhuang = gz[5] == '1';
|
||||
Rule.AAAIsZhaDan = gz[6] == '1';
|
||||
Rule.XiaJiaBaoDan = gz[7] == '1';
|
||||
Rule.ZhaDanDeFen = gz[9] == '1';
|
||||
Rule.HeiTao3BiChu = gz[11] == '1';
|
||||
switch (gz[10]) //设置托管
|
||||
{
|
||||
case '0':
|
||||
Rule.TuoGuanNum = 0;
|
||||
break;
|
||||
case '1':
|
||||
Rule.TuoGuanNum = 1;
|
||||
break;
|
||||
case '2':
|
||||
Rule.TuoGuanNum = 3;
|
||||
break;
|
||||
case '3':
|
||||
Rule.TuoGuanNum = 5;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 闹钟计时器
|
||||
/// </summary>
|
||||
public int TimeNum = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 包庄托管
|
||||
/// </summary>
|
||||
void BaoZhuangTuoGuan()
|
||||
{
|
||||
// var seat = GamePack.Info.WhoPlay - 1;
|
||||
int count = 0;
|
||||
for (int i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
var pl = this.DeskGameDo.desk[i];
|
||||
if (pl != null && pl.isDePosit)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count == 0) return; //不需要托管
|
||||
//GamePack.Info.PlayTuoGauan[seat] = 1;
|
||||
for (byte i = 0; i < GamePack.Info.PlayNum; i++)
|
||||
{
|
||||
var pl = this.DeskGameDo.desk[i];
|
||||
if (GamePack.Info.BaoZhuang[i] == 0 && pl != null && pl.isDePosit)
|
||||
{
|
||||
GamePack.Info.BaoZhuang[i] = 2;
|
||||
}
|
||||
}
|
||||
Debug.Info("包庄托管!GameDo");
|
||||
GameDo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回黑桃三的下标
|
||||
/// </summary>
|
||||
/// <param name="cards">可以出的牌组合</param>
|
||||
/// <param name="index">返回黑桃三的下标</param>
|
||||
/// <returns>false没有黑桃三 true有黑桃三</returns>
|
||||
bool GetHei3Index(List<List<TCardInfoPdkF>> cards, out int index)
|
||||
{
|
||||
index = -1;
|
||||
try
|
||||
{
|
||||
|
||||
if (cards == null || cards.Count <= 0) return false;
|
||||
bool isfirstChu = GamePack.Info.PlayNum == 2 ? GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1]
|
||||
: GamePack.Info.ShenYuCard[0] == GamePack.Info.ShenYuCard[1] && GamePack.Info.ShenYuCard[1] == GamePack.Info.ShenYuCard[2];
|
||||
if (!isfirstChu) return false; //如果不是第一次出牌, 就不管
|
||||
for (int i = 0; i < cards.Count; i++)
|
||||
{
|
||||
if (cards[i] == null || cards[i].Count <= 0) continue;
|
||||
if (cards[i][0].Flower == 1 && cards[i][0].GameNum == 3)
|
||||
{
|
||||
index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Error($"返回黑桃三的下标 msg:{e.Message},code:{e.StackTrace}");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打牌托管
|
||||
/// </summary>
|
||||
void DaPaiTuoGuan()
|
||||
{
|
||||
var seat = GamePack.Info.WhoPlay - 1;
|
||||
var pl = this.DeskGameDo.desk[seat];
|
||||
if (pl == null) return; //不需要托管
|
||||
if (Rule.BiYa)
|
||||
{
|
||||
if (pl.outline == 0)
|
||||
{//玩家没有离线
|
||||
if (!pl.isDePosit) return; //不需要托管
|
||||
}
|
||||
else
|
||||
{//玩家离线
|
||||
if (!pl.isDePosit && GamePack.Info.MaxPlayCard.GameNum <= 0) return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!pl.isDePosit) return; //不需要托管
|
||||
}
|
||||
//GamePack.Info.PlayTuoGauan[seat] = 1; //加这个是为了兼容老客户端
|
||||
if (GamePack.Info.MaxPlayCard.GameNum <= 0)
|
||||
{ //托管先出
|
||||
var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
|
||||
GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray(),
|
||||
GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
|
||||
Rule.AAAIsZhaDan);
|
||||
var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 ? tishi.Count - 1 : 0;
|
||||
if (Rule.HeiTao3BiChu && logicMemory.WarCount == 0)
|
||||
{//如果首局黑桃三首次必出,第一次出牌就必出黑桃三
|
||||
var h3 = GetHei3Index(tishi, out var idx3);
|
||||
if (h3 && idx3 >= 0)
|
||||
{
|
||||
idx = idx3;
|
||||
}
|
||||
}
|
||||
var payCard = new PlayOutCardPdkF();
|
||||
payCard.Pos = (byte)GamePack.Info.WhoPlay;
|
||||
payCard.Type = CardType1.DanZhang;
|
||||
payCard.GameNum = tishi[idx][0].GameNum;
|
||||
payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
|
||||
Log($"who:{GamePack.Info.WhoPlay}先出 ,托管出的牌:{payCard}");
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
}
|
||||
else
|
||||
{
|
||||
var shoupai = GamePack.CardPack.Cards[GamePack.Info.WhoPlay - 1].CardInfos.Where(x => x.GameState == 1).ToArray();
|
||||
var tishi = PdkCardAlgorithm.GetTipCard(GamePack.Info.MaxPlayCard,
|
||||
shoupai,
|
||||
GamePack.Info.MaxPlayCard.Pos == 0 ? null : GamePack.CardPack.Cards[GamePack.Info.MaxPlayCard.Pos - 1].CardInfos,
|
||||
Rule.AAAIsZhaDan, true);
|
||||
var payCard = new PlayOutCardPdkF();
|
||||
payCard.Pos = (byte)GamePack.Info.WhoPlay;
|
||||
if (tishi == null || tishi.Count <= 0)
|
||||
{
|
||||
payCard.Type = CardType1.None;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pl.outline == 1 && !pl.isDePosit) return; //玩家离线并且没有到托管时间
|
||||
payCard.Type = PdkCardAlgorithm.IsZhaDan(tishi[tishi.Count - 1].ToArray(), Rule.AAAIsZhaDan) ? CardType1.ZhaDan : GamePack.Info.MaxPlayCard.Type;
|
||||
var idx = Rule.XiaJiaBaoDan && GamePack.Info.ShenYuCard[GetNextPos(GamePack.Info.WhoPlay) - 1] == 1 && payCard.Type == CardType1.DanZhang ? 0 : tishi.Count - 1;
|
||||
payCard.GameNum = tishi[idx][0].GameNum;
|
||||
payCard.Ids = tishi[idx].Select(x => x.ID).ToArray();
|
||||
if (payCard.Type == CardType1.FeiJi || payCard.Type == CardType1.SanDai2)
|
||||
{
|
||||
int n = (payCard.Ids.Length / 3) * 2;
|
||||
var chaCard = shoupai.Except(tishi[idx]);
|
||||
List<TCardInfoPdkF> chupais = new List<TCardInfoPdkF>(16);
|
||||
chupais.AddRange(tishi[idx]);
|
||||
chupais.AddRange(chaCard.Reverse().Take(n));
|
||||
payCard.Ids = chupais.Select(x => x.ID).ToArray();
|
||||
}
|
||||
}
|
||||
Log($"who:{GamePack.Info.WhoPlay}跟牌 pai:{GamePack.Info.MaxPlayCard}托管出的牌:{payCard}");
|
||||
GamePack.Info.ActivePlayCard = payCard;
|
||||
}
|
||||
Debug.Info("打牌托管GameDo!");
|
||||
GameDo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 游戏临时加载的初始化
|
||||
/// </summary>
|
||||
public void LoadInit()
|
||||
{
|
||||
logicMemory.Init();
|
||||
TimeNum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
108
PdkFriendServer/PdkFriendServer.csproj
Normal file
108
PdkFriendServer/PdkFriendServer.csproj
Normal file
@ -0,0 +1,108 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
|
||||
<RootNamespace>PdkFriendServer</RootNamespace>
|
||||
<AssemblyName>PdkFriendServer</AssemblyName>
|
||||
|
||||
<Deterministic>true</Deterministic>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\exe\PdkFriendServer\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\exe\PdkFriendServer_Re\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Costura.Fody" PrivateAssets="all" />
|
||||
<PackageReference Include="Fody" PrivateAssets="all" />
|
||||
<PackageReference Include="MessagePack.Annotations" />
|
||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" />
|
||||
<PackageReference Include="Microsoft.NET.StringTools" />
|
||||
<PackageReference Include="System.Buffers" />
|
||||
<PackageReference Include="System.Memory" />
|
||||
<PackageReference Include="System.Numerics.Vectors" />
|
||||
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ServerCore\ServerCore.csproj" />
|
||||
<ProjectReference Include="..\GameFix\GameFix.csproj" />
|
||||
<ProjectReference Include="..\GameModule\GameModule.csproj" />
|
||||
<ProjectReference Include="..\GlobalSever\GlobalSever.csproj" />
|
||||
<ProjectReference Include="..\MrWu\MrWu.csproj" />
|
||||
<ProjectReference Include="..\NetWorkMessage\NetWorkMessage.csproj" />
|
||||
<ProjectReference Include="..\ObjectModel\ObjectModel.csproj" />
|
||||
<ProjectReference Include="..\ServerData\ServerData.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- <ItemGroup>-->
|
||||
<!-- <Compile Include="..\..\hjha_Client\Assets\ScriptCode\UnityGame\GamePlay\Card\Common\PaoDeKuaiF\GameFix\**\*.cs">-->
|
||||
<!-- <Link>GameFix\%(RecursiveDir)%(Filename)%(Extension)</Link>-->
|
||||
<!-- </Compile>-->
|
||||
<!-- </ItemGroup>-->
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Form1.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Form1.Designer.cs">
|
||||
<DependentUpon>Form1.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<AutoGen>true</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
<DesignTime>true</DesignTime>
|
||||
</Compile>
|
||||
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<AutoGen>true</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>true</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
|
||||
<None Update="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
30
PdkFriendServer/Program.cs
Normal file
30
PdkFriendServer/Program.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using GlobalSever.Form;
|
||||
using PdkFriendServer.GlobalManager;
|
||||
using PdkFriendServer.Logic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace PdkFriendServer
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new ServerForm(new GameServerProxy(), args));
|
||||
//PdkGameMain main = new PdkGameMain(null);
|
||||
//main.Test();
|
||||
//Console.ReadLine();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
36
PdkFriendServer/Properties/AssemblyInfo.cs
Normal file
36
PdkFriendServer/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("PdkFriendServer")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("PdkFriendServer")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("51c87339-4bbc-425a-b2d1-4488d0841b42")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
|
||||
//通过使用 "*",如下所示:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
71
PdkFriendServer/Properties/Resources.Designer.cs
generated
Normal file
71
PdkFriendServer/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,71 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PdkFriendServer.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PdkFriendServer.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重写当前线程的 CurrentUICulture 属性,对
|
||||
/// 使用此强类型资源类的所有资源查找执行重写。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
PdkFriendServer/Properties/Resources.resx
Normal file
117
PdkFriendServer/Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
PdkFriendServer/Properties/Settings.Designer.cs
generated
Normal file
30
PdkFriendServer/Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,30 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace PdkFriendServer.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
PdkFriendServer/Properties/Settings.settings
Normal file
7
PdkFriendServer/Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
Reference in New Issue
Block a user