Aggiungere i file di progetto.
This commit is contained in:
commit
f0855b9589
82
.editorconfig
Normal file
82
.editorconfig
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
[*.cs]
|
||||||
|
|
||||||
|
# IDE0090: Use 'new(...)'
|
||||||
|
dotnet_diagnostic.IDE0090.severity = none
|
||||||
|
csharp_indent_labels = one_less_than_current
|
||||||
|
csharp_space_around_binary_operators = before_and_after
|
||||||
|
csharp_using_directive_placement = outside_namespace:silent
|
||||||
|
csharp_prefer_simple_using_statement = true:suggestion
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
csharp_style_namespace_declarations = block_scoped:silent
|
||||||
|
csharp_style_prefer_method_group_conversion = true:silent
|
||||||
|
csharp_style_prefer_top_level_statements = true:silent
|
||||||
|
csharp_style_prefer_primary_constructors = true:suggestion
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
csharp_style_expression_bodied_lambdas = true:silent
|
||||||
|
csharp_style_expression_bodied_local_functions = false:silent
|
||||||
|
|
||||||
|
[*.{cs,vb}]
|
||||||
|
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||||
|
tab_width = 4
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = crlf
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:silent
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_prefer_collection_expression = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||||
|
[*.{cs,vb}]
|
||||||
|
#### Naming styles ####
|
||||||
|
|
||||||
|
# Naming rules
|
||||||
|
|
||||||
|
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
|
||||||
|
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
|
||||||
|
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
|
||||||
|
|
||||||
|
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
|
||||||
|
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
|
||||||
|
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
|
||||||
|
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
|
||||||
|
|
||||||
|
# Symbol specifications
|
||||||
|
|
||||||
|
dotnet_naming_symbols.interface.applicable_kinds = interface
|
||||||
|
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.interface.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
|
||||||
|
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.types.required_modifiers =
|
||||||
|
|
||||||
|
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||||
|
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||||
|
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||||
|
|
||||||
|
# Naming styles
|
||||||
|
|
||||||
|
dotnet_naming_style.begins_with_i.required_prefix = I
|
||||||
|
dotnet_naming_style.begins_with_i.required_suffix =
|
||||||
|
dotnet_naming_style.begins_with_i.word_separator =
|
||||||
|
dotnet_naming_style.begins_with_i.capitalization = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_style.pascal_case.required_prefix =
|
||||||
|
dotnet_naming_style.pascal_case.required_suffix =
|
||||||
|
dotnet_naming_style.pascal_case.word_separator =
|
||||||
|
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
||||||
|
|
||||||
|
dotnet_naming_style.pascal_case.required_prefix =
|
||||||
|
dotnet_naming_style.pascal_case.required_suffix =
|
||||||
|
dotnet_naming_style.pascal_case.word_separator =
|
||||||
|
dotnet_naming_style.pascal_case.capitalization = pascal_case
|
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
37
.github/workflows/nightly.yml
vendored
Normal file
37
.github/workflows/nightly.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# This workflow will build a .NET project
|
||||||
|
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
|
||||||
|
|
||||||
|
name: Nightly
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
schedule:
|
||||||
|
# This runs every day at midnight: https://crontab.guru/#0_0_*_*_*
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, ubuntu-latest]
|
||||||
|
include:
|
||||||
|
- os: windows-latest
|
||||||
|
build: Campofinale-${{github.ref_name}}-Windows
|
||||||
|
- os: ubuntu-latest
|
||||||
|
build: Campofinale-${{github.ref_name}}-Linux
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: 8.0.x
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build --no-restore --configuration Release
|
||||||
|
- name: Upload Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.build }}
|
||||||
|
path: Campofinale/bin/Release/net8.0
|
36
.github/workflows/stable.yml
vendored
Normal file
36
.github/workflows/stable.yml
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# This workflow will build a .NET project
|
||||||
|
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
|
||||||
|
|
||||||
|
name: Stable
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, ubuntu-latest]
|
||||||
|
include:
|
||||||
|
- os: windows-latest
|
||||||
|
build: Campofinale-${{github.ref_name}}-Windows
|
||||||
|
- os: ubuntu-latest
|
||||||
|
build: Campofinale-${{github.ref_name}}-Linux
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Setup .NET
|
||||||
|
uses: actions/setup-dotnet@v4
|
||||||
|
with:
|
||||||
|
dotnet-version: 8.0.x
|
||||||
|
- name: Restore dependencies
|
||||||
|
run: dotnet restore
|
||||||
|
- name: Build
|
||||||
|
run: dotnet build --no-restore --configuration Release
|
||||||
|
- name: Upload Artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.build }}
|
||||||
|
path: Campofinale/bin/Release/net8.0
|
366
.gitignore
vendored
Normal file
366
.gitignore
vendored
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Oo]ut/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
decrypter/
|
||||||
|
endfield-cbt2-dumps/
|
901
Campofinale.Protocol/Campofinale.Protocol.csproj
Normal file
901
Campofinale.Protocol/Campofinale.Protocol.csproj
Normal file
@ -0,0 +1,901 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<AnalysisLevel>6.0</AnalysisLevel>
|
||||||
|
<Platforms>AnyCPU;ARM32</Platforms>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Google.Protobuf" Version="3.25.0" />
|
||||||
|
<PackageReference Include="Google.Protobuf.Tools" Version="3.25.0" />
|
||||||
|
<PackageReference Include="Grpc.Tools" Version="2.59.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Protobuf Include="*.proto" ProtoRoot="." GrpcServices="None" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="AbilityActionCreateGadget.proto" />
|
||||||
|
<None Remove="AbilityActionSummon.proto" />
|
||||||
|
<None Remove="AbilityAppliedAbility.proto" />
|
||||||
|
<None Remove="AbilityArgument.proto" />
|
||||||
|
<None Remove="AbilityBornType.proto" />
|
||||||
|
<None Remove="AbilityGadgetInfo.proto" />
|
||||||
|
<None Remove="AbilityInvocationFailNotify.proto" />
|
||||||
|
<None Remove="AbilityInvocationsNotify.proto" />
|
||||||
|
<None Remove="AbilityInvokeEntry.proto" />
|
||||||
|
<None Remove="AbilityMetaAddAbility.proto" />
|
||||||
|
<None Remove="AbilityMetaModifierChange.proto" />
|
||||||
|
<None Remove="AbilityMetaSetAbilityTrigger.proto" />
|
||||||
|
<None Remove="AbilityMetaSetModifierApplyEntityId.proto" />
|
||||||
|
<None Remove="AbilityMixinAvatarSteerByCamera.proto" />
|
||||||
|
<None Remove="AbilityMixinElementShield.proto" />
|
||||||
|
<None Remove="AbilityMixinEmpty.proto" />
|
||||||
|
<None Remove="AbilityResetReason.proto" />
|
||||||
|
<None Remove="AbilityScalarType.proto" />
|
||||||
|
<None Remove="AbilityString.proto" />
|
||||||
|
<None Remove="AddQuestContentProgressReq.proto" />
|
||||||
|
<None Remove="AddSeenMonsterNotify.proto" />
|
||||||
|
<None Remove="AllSeenMonsterNotify.proto" />
|
||||||
|
<None Remove="AnimatorParameterValueInfo.proto" />
|
||||||
|
<None Remove="AREA_TYPE.proto" />
|
||||||
|
<None Remove="AREA_UNLOCK_INFO.proto" />
|
||||||
|
<None Remove="AttackHitEffectResult.proto" />
|
||||||
|
<None Remove="ATTR_INFO.proto" />
|
||||||
|
<None Remove="AuthkeySignType.proto" />
|
||||||
|
<None Remove="AuthRequest.proto" />
|
||||||
|
<None Remove="AuthResponse.proto" />
|
||||||
|
<None Remove="AvatarAddNotify.proto" />
|
||||||
|
<None Remove="AvatarCardChangeRsp.proto" />
|
||||||
|
<None Remove="AvatarChangeElementTypeRsp.proto" />
|
||||||
|
<None Remove="AvatarDelNotify.proto" />
|
||||||
|
<None Remove="AvatarDieAnimationEndRsp.proto" />
|
||||||
|
<None Remove="AvatarEnterSceneInfo.proto" />
|
||||||
|
<None Remove="AvatarFightPropNotify.proto" />
|
||||||
|
<None Remove="AvatarInfo.proto" />
|
||||||
|
<None Remove="AvatarPromoteReq.proto" />
|
||||||
|
<None Remove="AvatarPropChangeReasonNotify.proto" />
|
||||||
|
<None Remove="AvatarSkillDepotChangeNotify.proto" />
|
||||||
|
<None Remove="AvatarSkillInfoNotify.proto" />
|
||||||
|
<None Remove="AvatarTeam.proto" />
|
||||||
|
<None Remove="AvatarUnlockTalentNotify.proto" />
|
||||||
|
<None Remove="AvatarUpgradeRsp.proto" />
|
||||||
|
<None Remove="BackMyWorldRsp.proto" />
|
||||||
|
<None Remove="BATTLE_INFO.proto" />
|
||||||
|
<None Remove="BigTalentPointConvertReq.proto" />
|
||||||
|
<None Remove="BITSET_DATA.proto" />
|
||||||
|
<None Remove="BLOC_INFO.proto" />
|
||||||
|
<None Remove="BuffAddNotify.proto" />
|
||||||
|
<None Remove="BuyGoodsReq.proto" />
|
||||||
|
<None Remove="CellInfo.proto" />
|
||||||
|
<None Remove="ChangeAvatarReq.proto" />
|
||||||
|
<None Remove="ChangeGameTimeReq.proto" />
|
||||||
|
<None Remove="ChangHpReason.proto" />
|
||||||
|
<None Remove="ChapterStateNotify.proto" />
|
||||||
|
<None Remove="CHAR_INFO.proto" />
|
||||||
|
<None Remove="CHAR_TEAM_INFO.proto" />
|
||||||
|
<None Remove="CHAR_TEAM_MEMBER_INFO.proto" />
|
||||||
|
<None Remove="ChooseCurAvatarTeamReq.proto" />
|
||||||
|
<None Remove="CityInfo.proto" />
|
||||||
|
<None Remove="ClientAbilityInitFinishNotify.proto" />
|
||||||
|
<None Remove="ClientGadgetInfo.proto" />
|
||||||
|
<None Remove="ClientPauseNotify.proto" />
|
||||||
|
<None Remove="ClientReconnectReason.proto" />
|
||||||
|
<None Remove="ClientTransmitReq.proto" />
|
||||||
|
<None Remove="ClientTriggerEventNotify.proto" />
|
||||||
|
<None Remove="CLIENT_PLATFORM_TYPE.proto" />
|
||||||
|
<None Remove="CmdAbilityReflection.proto" />
|
||||||
|
<None Remove="CmdFightReflection.proto" />
|
||||||
|
<None Remove="cmdids.csv" />
|
||||||
|
<None Remove="CmdItemReflection.proto" />
|
||||||
|
<None Remove="CmdMiscReflection.proto" />
|
||||||
|
<None Remove="CmdNpcReflection.proto" />
|
||||||
|
<None Remove="CmdPropertyReflection.proto" />
|
||||||
|
<None Remove="CmdSceneReflection.proto" />
|
||||||
|
<None Remove="CmdSkillReflection.proto" />
|
||||||
|
<None Remove="Component.proto" />
|
||||||
|
<None Remove="ComponentBoxConveyor.proto" />
|
||||||
|
<None Remove="ComponentBoxRouter.proto" />
|
||||||
|
<None Remove="ComponentCache.proto" />
|
||||||
|
<None Remove="ComponentCollector.proto" />
|
||||||
|
<None Remove="ComponentInventory.proto" />
|
||||||
|
<None Remove="ComponentMap.proto" />
|
||||||
|
<None Remove="ComponentProducer.proto" />
|
||||||
|
<None Remove="ComponentSelector.proto" />
|
||||||
|
<None Remove="ComponentTransform.proto" />
|
||||||
|
<None Remove="ComponentType.proto" />
|
||||||
|
<None Remove="CompoundDataNotify.proto" />
|
||||||
|
<None Remove="ContextArchive.proto" />
|
||||||
|
<None Remove="ContextBlackboard.proto" />
|
||||||
|
<None Remove="ContextBrief.proto" />
|
||||||
|
<None Remove="ContextStatus.proto" />
|
||||||
|
<None Remove="CookDataNotify.proto" />
|
||||||
|
<None Remove="CookRecipeData.proto" />
|
||||||
|
<None Remove="COST_ITEM_LIST_DEF.proto" />
|
||||||
|
<None Remove="CreateEntityInfo.proto" />
|
||||||
|
<None Remove="CreateReason.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_INTERACTIVE_PARAM.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OBSERVER_PAYLOAD_OP_CHECKOUT_CHARACTER_WORK.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OBSERVER_PAYLOAD_OP_CHECKOUT_OUTSIDE_RESOURCE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OBSERVER_PAYLOAD_OP_CHECKOUT_POWER_CONNECTION_MAP.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OBSERVER_PAYLOAD_OP_CHECKOUT_RELATION_BOARD.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_ADD_CONNECTION.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_CACHE_TRANSPORT_ENABLE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_CACHE_TRANSPORT_TRANSFER.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_DEL_CONNECTION.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_DISMANTLE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_DISMANTLE_BOX_CONVEYOR.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_ENABLE_NODE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_GRID_BOX_INNER_MOVE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_GRID_BOX_INNER_SPLIT.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_BAG_TO_CACHE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_BAG_TO_GRID_BOX.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_CACHE_TO_BAG.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_CACHE_TO_CACHE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_CACHE_TO_DEPOT.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_CONVEYOR_TO_BAG.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_DEPOT_TO_CACHE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_DEPOT_TO_GRID_BOX.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_GRID_BOX_TO_BAG.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_ITEM_GRID_BOX_TO_DEPOT.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_MOVE_NODE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_PLACE.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_PLACE_BOX_CONVEYOR.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_SET_COLLECT_TARGET.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_SET_SELECT_TARGET.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_SET_TRAVEL_POLE_DEFAULT_NEXT.proto" />
|
||||||
|
<None Remove="CSD_FACTORY_OP_USE_HEAL_TOWER_POINT.proto" />
|
||||||
|
<None Remove="CSD_SP_INTERACTIVE_DOODAD_COMMON_BREAK.proto" />
|
||||||
|
<None Remove="CSD_SP_INTERACTIVE_DOODAD_COMMON_PICK.proto" />
|
||||||
|
<None Remove="CSHead.proto" />
|
||||||
|
<None Remove="CS_ACCEPT_MISSION.proto" />
|
||||||
|
<None Remove="CS_ACHIEVE_COMPLETE.proto" />
|
||||||
|
<None Remove="CS_ACHIEVE_TAKE_REWARD.proto" />
|
||||||
|
<None Remove="CS_BITSET_ADD.proto" />
|
||||||
|
<None Remove="CS_BITSET_REMOVE.proto" />
|
||||||
|
<None Remove="CS_BITSET_REMOVE_ALL.proto" />
|
||||||
|
<None Remove="CS_BLOC_SHOP_BUY.proto" />
|
||||||
|
<None Remove="CS_CHAR_BAG_SET_CURR_TEAM_INDEX.proto" />
|
||||||
|
<None Remove="CS_CHAR_BAG_SET_TEAM.proto" />
|
||||||
|
<None Remove="CS_CHAR_BAG_SET_TEAM_LEADER.proto" />
|
||||||
|
<None Remove="CS_CHAR_BAG_SET_TEAM_NAME.proto" />
|
||||||
|
<None Remove="CS_CHAR_BREAK.proto" />
|
||||||
|
<None Remove="CS_CHAR_LEVEL_UP.proto" />
|
||||||
|
<None Remove="CS_CHAR_SET_BATTLE_INFO.proto" />
|
||||||
|
<None Remove="CS_CHAR_SET_NORMAL_SKILL.proto" />
|
||||||
|
<None Remove="CS_CHAR_SET_TEAM_SKILL.proto" />
|
||||||
|
<None Remove="CS_CHAR_SKILL_LEVEL_UP.proto" />
|
||||||
|
<None Remove="CS_COMPLETE_GUIDE_GROUP.proto" />
|
||||||
|
<None Remove="CS_COMPLETE_GUIDE_GROUP_KEY_STEP.proto" />
|
||||||
|
<None Remove="CS_CREATE_ROLE.proto" />
|
||||||
|
<None Remove="CS_DELETE_ALL_MAIL.proto" />
|
||||||
|
<None Remove="CS_DELETE_MAIL.proto" />
|
||||||
|
<None Remove="CS_DUNGEON_RECOVER_AP.proto" />
|
||||||
|
<None Remove="CS_DUNGEON_REWARD.proto" />
|
||||||
|
<None Remove="CS_ENTER_DUNGEON.proto" />
|
||||||
|
<None Remove="CS_ENTER_SCENE.proto" />
|
||||||
|
<None Remove="CS_EQUIP_PUTOFF.proto" />
|
||||||
|
<None Remove="CS_EQUIP_PUTON.proto" />
|
||||||
|
<None Remove="CS_FACTORY_CHARACTER_WORK_PUNCH_IN.proto" />
|
||||||
|
<None Remove="CS_FACTORY_CHARACTER_WORK_PUNCH_OUT.proto" />
|
||||||
|
<None Remove="CS_FACTORY_HS_FB.proto" />
|
||||||
|
<None Remove="CS_FACTORY_HS_INOUT.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUALLY_WORK_APPEND.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUALLY_WORK_CANCEL.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUALLY_WORK_PAUSE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUALLY_WORK_RESUME.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUFACTURE_CANCEL.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUFACTURE_SETTLE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_MANUFACTURE_START.proto" />
|
||||||
|
<None Remove="CS_FACTORY_OBSERVER_OP.proto" />
|
||||||
|
<None Remove="CS_FACTORY_OP.proto" />
|
||||||
|
<None Remove="CS_FACTORY_PROCESSOR_MAKE_EQUIP.proto" />
|
||||||
|
<None Remove="CS_FACTORY_PROCESSOR_MAKE_GEM.proto" />
|
||||||
|
<None Remove="CS_FACTORY_PROCESSOR_MAKE_ITEM.proto" />
|
||||||
|
<None Remove="CS_FACTORY_PROCESSOR_MARK_UNLOCK_FORMULA_READ.proto" />
|
||||||
|
<None Remove="CS_FACTORY_PROCESSOR_RECAST_GEM.proto" />
|
||||||
|
<None Remove="CS_FACTORY_QUICKBAR_MOVE_ONE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_QUICKBAR_SET_ONE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_RECYCLER_COMMIT_MATERIAL.proto" />
|
||||||
|
<None Remove="CS_FACTORY_RECYCLER_FETCH_PRODUCT.proto" />
|
||||||
|
<None Remove="CS_FACTORY_REPAIR_BUILDING.proto" />
|
||||||
|
<None Remove="CS_FACTORY_SOIL_CANCEL.proto" />
|
||||||
|
<None Remove="CS_FACTORY_SOIL_HARVEST.proto" />
|
||||||
|
<None Remove="CS_FACTORY_SOIL_PLANT.proto" />
|
||||||
|
<None Remove="CS_FACTORY_STATISTIC_REQUIRE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_STATISTIC_SET_BOOKMARK_ITEM_IDS.proto" />
|
||||||
|
<None Remove="CS_FACTORY_STT_UNLOCK_NODE.proto" />
|
||||||
|
<None Remove="CS_FACTORY_TRADE_CASH_ORDER.proto" />
|
||||||
|
<None Remove="CS_FACTORY_TRADE_DELETE_ORDER.proto" />
|
||||||
|
<None Remove="CS_FACTORY_TRADE_SET_CONTRACT.proto" />
|
||||||
|
<None Remove="CS_FACTORY_WORKSHOP_MAKE.proto" />
|
||||||
|
<None Remove="CS_FAIL_MISSION.proto" />
|
||||||
|
<None Remove="CS_FINISH_DIALOG.proto" />
|
||||||
|
<None Remove="CS_FLUSH_SYNC.proto" />
|
||||||
|
<None Remove="CS_GET_ALL_MAIL_ATTACHMENT.proto" />
|
||||||
|
<None Remove="CS_GET_MAIL.proto" />
|
||||||
|
<None Remove="CS_GET_MAIL_ATTACHMENT.proto" />
|
||||||
|
<None Remove="CS_GM_COMMAND.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_BAG_TO_FACTORY_DEPOT.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_DESTROY_IN_BAG.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_DESTROY_IN_DEPOT.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_FACTORY_DEPOT_TO_BAG.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_FACTORY_DEPOT_TO_BAG_GRID.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_MOVE_IN_BAG.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_SET_ITEM_LOCK.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_SET_QUICK_BAR.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_SET_QUICK_BAR_POS.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_SPLIT_IN_BAG.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_TIDY_IN_BAG.proto" />
|
||||||
|
<None Remove="CS_ITEM_BAG_USE_ITEM.proto" />
|
||||||
|
<None Remove="CS_LEAVE_DUNGEON.proto" />
|
||||||
|
<None Remove="CS_LOGIN.proto" />
|
||||||
|
<None Remove="CS_LOGOUT.proto" />
|
||||||
|
<None Remove="CS_MAIL_DEF.proto" />
|
||||||
|
<None Remove="CS_MARK_WIKI_READ.proto" />
|
||||||
|
<None Remove="CS_MERGE_MSG.proto" />
|
||||||
|
<None Remove="CS_MOVE_OBJECT_MOVE.proto" />
|
||||||
|
<None Remove="CS_PING.proto" />
|
||||||
|
<None Remove="CS_PRTS_MARK_READ.proto" />
|
||||||
|
<None Remove="CS_PRTS_MARK_TERMINAL_READ.proto" />
|
||||||
|
<None Remove="CS_READ_MAIL.proto" />
|
||||||
|
<None Remove="CS_RED_DOT_READ_FORMULA.proto" />
|
||||||
|
<None Remove="CS_REMOVE_ITEM_NEW_TAGS.proto" />
|
||||||
|
<None Remove="CS_RESTART_DUNGEON.proto" />
|
||||||
|
<None Remove="CS_ROLL_BLOC_MISSION.proto" />
|
||||||
|
<None Remove="CS_SCENE_COMMIT_LEVEL_SCRIPT_CACHE_STEP.proto" />
|
||||||
|
<None Remove="CS_SCENE_CREATE_ENTITY.proto" />
|
||||||
|
<None Remove="CS_SCENE_DESTROY_ENTITY.proto" />
|
||||||
|
<None Remove="CS_SCENE_INTERACTIVE_EVENT_TRIGGER.proto" />
|
||||||
|
<None Remove="CS_SCENE_INTERACT_SP_INTERACTIVE.proto" />
|
||||||
|
<None Remove="CS_SCENE_INTERACT_TREE.proto" />
|
||||||
|
<None Remove="CS_SCENE_KILL_CHAR.proto" />
|
||||||
|
<None Remove="CS_SCENE_KILL_MONSTER.proto" />
|
||||||
|
<None Remove="CS_SCENE_LEVEL_SCRIPT_EVENT_TRIGGER.proto" />
|
||||||
|
<None Remove="CS_SCENE_LOAD_FINISH.proto" />
|
||||||
|
<None Remove="CS_SCENE_MAP_MARK_CREATE.proto" />
|
||||||
|
<None Remove="CS_SCENE_MAP_MARK_UPDATE_STATE.proto" />
|
||||||
|
<None Remove="CS_SCENE_MOVE_STATE_SET.proto" />
|
||||||
|
<None Remove="CS_SCENE_QUERY_ENTITY_EXIST.proto" />
|
||||||
|
<None Remove="CS_SCENE_QUERY_INTERACTIVE_PROPERTY.proto" />
|
||||||
|
<None Remove="CS_SCENE_REPATRIATE.proto" />
|
||||||
|
<None Remove="CS_SCENE_RESET_ENTITY.proto" />
|
||||||
|
<None Remove="CS_SCENE_RESET_LEVEL_SCRIPT.proto" />
|
||||||
|
<None Remove="CS_SCENE_REST.proto" />
|
||||||
|
<None Remove="CS_SCENE_REVIVAL.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_BATTLE.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_CHECK_POINT.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_LAST_RECORD_CAMPID.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_LEVEL_SCRIPT_ACTIVE.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_REPATRIATE_POINT.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_SAFE_ZONE.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_TRACK_POINT.proto" />
|
||||||
|
<None Remove="CS_SCENE_SET_VAR.proto" />
|
||||||
|
<None Remove="CS_SCENE_SPAWN_INTERACTIVE.proto" />
|
||||||
|
<None Remove="CS_SCENE_SPAWN_MONSTER.proto" />
|
||||||
|
<None Remove="CS_SCENE_SUBMIT_ETHER.proto" />
|
||||||
|
<None Remove="CS_SCENE_SUBMIT_ITEM.proto" />
|
||||||
|
<None Remove="CS_SCENE_TELEPORT.proto" />
|
||||||
|
<None Remove="CS_SCENE_UPDATE_INTERACTIVE_PROPERTY.proto" />
|
||||||
|
<None Remove="CS_SCENE_UPDATE_LEVEL_SCRIPT_PROPERTY.proto" />
|
||||||
|
<None Remove="CS_STOP_TRACKING_MISSION.proto" />
|
||||||
|
<None Remove="CS_TRACK_MISSION.proto" />
|
||||||
|
<None Remove="CS_UNLOCK_WIKI.proto" />
|
||||||
|
<None Remove="CS_UPDATE_QUEST_OBJECTIVE.proto" />
|
||||||
|
<None Remove="CS_WEAPON_ADD_EXP.proto" />
|
||||||
|
<None Remove="CS_WEAPON_ATTACH_GEM.proto" />
|
||||||
|
<None Remove="CS_WEAPON_BREAKTHROUGH.proto" />
|
||||||
|
<None Remove="CS_WEAPON_DETACH_GEM.proto" />
|
||||||
|
<None Remove="CS_WEAPON_PUTON.proto" />
|
||||||
|
<None Remove="CS_WIKI_PIN.proto" />
|
||||||
|
<None Remove="CutSceneEndNotify.proto" />
|
||||||
|
<None Remove="DataResVersionNotify.proto" />
|
||||||
|
<None Remove="DefineReflection.proto" />
|
||||||
|
<None Remove="DelMailRsp.proto" />
|
||||||
|
<None Remove="DIALOG.proto" />
|
||||||
|
<None Remove="Direction.proto" />
|
||||||
|
<None Remove="DISCOUNT_INFO.proto" />
|
||||||
|
<None Remove="DropHintNotify.proto" />
|
||||||
|
<None Remove="DropItemRsp.proto" />
|
||||||
|
<None Remove="DropSubfieldRsp.proto" />
|
||||||
|
<None Remove="DungeonChallengeBeginNotify.proto" />
|
||||||
|
<None Remove="DungeonDataNotify.proto" />
|
||||||
|
<None Remove="DungeonDieOptionReq.proto" />
|
||||||
|
<None Remove="DungeonEntryInfo.proto" />
|
||||||
|
<None Remove="DungeonEntryInfoRsp.proto" />
|
||||||
|
<None Remove="DungeonPlayerDieNotify.proto" />
|
||||||
|
<None Remove="DungeonPlayerDieRsp.proto" />
|
||||||
|
<None Remove="DungeonShowReminderNotify.proto" />
|
||||||
|
<None Remove="DungeonWayPointActivateRsp.proto" />
|
||||||
|
<None Remove="DYNAMIC_PARAMETER.proto" />
|
||||||
|
<None Remove="EditorReflection.proto" />
|
||||||
|
<None Remove="EncryptType.proto" />
|
||||||
|
<None Remove="ENetReason.proto" />
|
||||||
|
<None Remove="EnterSceneDoneRsp.proto" />
|
||||||
|
<None Remove="EnterSceneReadyReq.proto" />
|
||||||
|
<None Remove="EnterSceneWeatherAreaNotify.proto" />
|
||||||
|
<None Remove="EnterType.proto" />
|
||||||
|
<None Remove="EnterWorldAreaRsp.proto" />
|
||||||
|
<None Remove="EntityFightPropChangeReasonNotify.proto" />
|
||||||
|
<None Remove="EntityFightPropUpdateNotify.proto" />
|
||||||
|
<None Remove="EntityForceSyncRsp.proto" />
|
||||||
|
<None Remove="EntityMoveFailInfo.proto" />
|
||||||
|
<None Remove="EntityPropNotify.proto" />
|
||||||
|
<None Remove="ENTITY_INFO.proto" />
|
||||||
|
<None Remove="ENTITY_OP_TYPE.proto" />
|
||||||
|
<None Remove="ENV_TYPE.proto" />
|
||||||
|
<None Remove="EquipParam.proto" />
|
||||||
|
<None Remove="EQUIP_ATTR.proto" />
|
||||||
|
<None Remove="EQUIP_DATA.proto" />
|
||||||
|
<None Remove="Event.proto" />
|
||||||
|
<None Remove="EventComponentChg.proto" />
|
||||||
|
<None Remove="EventLayoutChg.proto" />
|
||||||
|
<None Remove="EventPrepared.proto" />
|
||||||
|
<None Remove="EventRelationChg.proto" />
|
||||||
|
<None Remove="EventTriggerType.proto" />
|
||||||
|
<None Remove="EventType.proto" />
|
||||||
|
<None Remove="EvtAnimatorParameterNotify.proto" />
|
||||||
|
<None Remove="EvtAvatarEnterFocusNotify.proto" />
|
||||||
|
<None Remove="EvtAvatarUpdateFocusNotify.proto" />
|
||||||
|
<None Remove="EvtBulletDeactiveNotify.proto" />
|
||||||
|
<None Remove="EvtBulletMoveNotify.proto" />
|
||||||
|
<None Remove="EvtCreateGadgetNotify.proto" />
|
||||||
|
<None Remove="EvtDoSkillSuccNotify.proto" />
|
||||||
|
<None Remove="EvtEntityStartDieEndNotify.proto" />
|
||||||
|
<None Remove="EvtFaceToEntityNotify.proto" />
|
||||||
|
<None Remove="EvtSetAttackTargetNotify.proto" />
|
||||||
|
<None Remove="ExecuteGadgetLuaRsp.proto" />
|
||||||
|
<None Remove="ExecuteGroupTriggerRsp.proto" />
|
||||||
|
<None Remove="ExitTransPointRegionNotify.proto" />
|
||||||
|
<None Remove="E_USE_ITEM_RESULT.proto" />
|
||||||
|
<None Remove="FACTORY_OP_RET_CODE.proto" />
|
||||||
|
<None Remove="FACTORY_OP_TYPE.proto" />
|
||||||
|
<None Remove="FACTORY_SOIL_HARVEST_TYPE.proto" />
|
||||||
|
<None Remove="FinishedParentQuestUpdateNotify.proto" />
|
||||||
|
<None Remove="Formula.proto" />
|
||||||
|
<None Remove="ForwardType.proto" />
|
||||||
|
<None Remove="GadgetInteractReq.proto" />
|
||||||
|
<None Remove="GadgetStateNotify.proto" />
|
||||||
|
<None Remove="GEM_DATA.proto" />
|
||||||
|
<None Remove="GENDER.proto" />
|
||||||
|
<None Remove="GetAllMailReq.proto" />
|
||||||
|
<None Remove="GetAuthkeyReq.proto" />
|
||||||
|
<None Remove="GetCompoundDataReq.proto" />
|
||||||
|
<None Remove="GetMailItemReq.proto" />
|
||||||
|
<None Remove="GetOnlinePlayerListReq.proto" />
|
||||||
|
<None Remove="GetPlayerTokenReq.proto" />
|
||||||
|
<None Remove="GetQuestTalkHistoryReq.proto" />
|
||||||
|
<None Remove="GetSceneAreaReq.proto" />
|
||||||
|
<None Remove="GetSceneNpcPostionReq.proto" />
|
||||||
|
<None Remove="GetScenePointReq.proto" />
|
||||||
|
<None Remove="GetShopReq.proto" />
|
||||||
|
<None Remove="GmTalkReq.proto" />
|
||||||
|
<None Remove="GrantRewardNotify.proto" />
|
||||||
|
<None Remove="GUIDE_GROUP_INFO.proto" />
|
||||||
|
<None Remove="Header.proto" />
|
||||||
|
<None Remove="HitColliderType.proto" />
|
||||||
|
<None Remove="HostPlayerNotify.proto" />
|
||||||
|
<None Remove="InterOpType.proto" />
|
||||||
|
<None Remove="ItemAddHintNotify.proto" />
|
||||||
|
<None Remove="ItemBox.proto" />
|
||||||
|
<None Remove="ItemCdGroupTimeNotify.proto" />
|
||||||
|
<None Remove="ItemParam.proto" />
|
||||||
|
<None Remove="ItemUnit.proto" />
|
||||||
|
<None Remove="ITEM_BUNDLE.proto" />
|
||||||
|
<None Remove="ITEM_INFO.proto" />
|
||||||
|
<None Remove="ITEM_INST.proto" />
|
||||||
|
<None Remove="ITEM_INST_EMPTY.proto" />
|
||||||
|
<None Remove="ITEM_INST_LOCK_INFO.proto" />
|
||||||
|
<None Remove="JoinPlayerSceneReq.proto" />
|
||||||
|
<None Remove="KeepAliveNotify.proto" />
|
||||||
|
<None Remove="LayoutShape.proto" />
|
||||||
|
<None Remove="LeaveSceneReq.proto" />
|
||||||
|
<None Remove="LEAVE_OBJECT_INFO.proto" />
|
||||||
|
<None Remove="LevelupCityReq.proto" />
|
||||||
|
<None Remove="LEVEL_SCRIPT_INFO.proto" />
|
||||||
|
<None Remove="LogBoolParam.proto" />
|
||||||
|
<None Remove="LogCutsceneNotify.proto" />
|
||||||
|
<None Remove="LogDoubleParam.proto" />
|
||||||
|
<None Remove="LogFloatParam.proto" />
|
||||||
|
<None Remove="LogIntParam.proto" />
|
||||||
|
<None Remove="LogLevel.proto" />
|
||||||
|
<None Remove="LogMessage.proto" />
|
||||||
|
<None Remove="LogMessageResponse.proto" />
|
||||||
|
<None Remove="LogStringParam.proto" />
|
||||||
|
<None Remove="LogTalkNotify.proto" />
|
||||||
|
<None Remove="MailData.proto" />
|
||||||
|
<None Remove="MAIL_CONTENT.proto" />
|
||||||
|
<None Remove="MapInfo.proto" />
|
||||||
|
<None Remove="Material.proto" />
|
||||||
|
<None Remove="MeshArea.proto" />
|
||||||
|
<None Remove="MeshAreaBitmap.proto" />
|
||||||
|
<None Remove="MessageType.proto" />
|
||||||
|
<None Remove="MISSION.proto" />
|
||||||
|
<None Remove="MISSION_STATE.proto" />
|
||||||
|
<None Remove="ModifierAction.proto" />
|
||||||
|
<None Remove="MONEY_INFO.proto" />
|
||||||
|
<None Remove="MonsterAlertChangeNotify.proto" />
|
||||||
|
<None Remove="MonsterForceAiNotify.proto" />
|
||||||
|
<None Remove="MonsterSummonTagNotify.proto" />
|
||||||
|
<None Remove="MotionState.proto" />
|
||||||
|
<None Remove="MOTION_INFO.proto" />
|
||||||
|
<None Remove="MOTION_STATE.proto" />
|
||||||
|
<None Remove="MOVE_OBJECT_MOVE_INFO.proto" />
|
||||||
|
<None Remove="Node.proto" />
|
||||||
|
<None Remove="NodeType.proto" />
|
||||||
|
<None Remove="NpcPostionInfo.proto" />
|
||||||
|
<None Remove="NpcTalkReq.proto" />
|
||||||
|
<None Remove="NpcTalkState.proto" />
|
||||||
|
<None Remove="NpcTalkType.proto" />
|
||||||
|
<None Remove="OBJECTIVE_VALUE_OP.proto" />
|
||||||
|
<None Remove="OnlinePlayerState.proto" />
|
||||||
|
<None Remove="OpenStateUpdateNotify.proto" />
|
||||||
|
<None Remove="Operate.proto" />
|
||||||
|
<None Remove="OperatePayloadAddNewArea.proto" />
|
||||||
|
<None Remove="OperatePayloadDismantle.proto" />
|
||||||
|
<None Remove="OperatePayloadPlace.proto" />
|
||||||
|
<None Remove="OperatePayloadPlaceConveyor.proto" />
|
||||||
|
<None Remove="OperatePayloadPutInItemsToCache.proto" />
|
||||||
|
<None Remove="OperatePayloadSetCollectTarget.proto" />
|
||||||
|
<None Remove="OperatePayloadSetEventEnable.proto" />
|
||||||
|
<None Remove="OperatePayloadSetUnloaderSelect.proto" />
|
||||||
|
<None Remove="OperatePayloadTakeOutItemsFromCache.proto" />
|
||||||
|
<None Remove="OperateRetCode.proto" />
|
||||||
|
<None Remove="OperateReturn.proto" />
|
||||||
|
<None Remove="OperateReturnPlace.proto" />
|
||||||
|
<None Remove="OperateReturnPlaceConveyor.proto" />
|
||||||
|
<None Remove="OperateReturnPutInItemsToCache.proto" />
|
||||||
|
<None Remove="OperateReturnTakeOutItemsFromCache.proto" />
|
||||||
|
<None Remove="OperateType.proto" />
|
||||||
|
<None Remove="ParamList.proto" />
|
||||||
|
<None Remove="ParentQuestRandomInfo.proto" />
|
||||||
|
<None Remove="PersonalSceneJumpRsp.proto" />
|
||||||
|
<None Remove="PingRsp.proto" />
|
||||||
|
<None Remove="PlatformChangeRouteNotify.proto" />
|
||||||
|
<None Remove="PlatformStartRouteNotify.proto" />
|
||||||
|
<None Remove="PlayerCompoundMaterialReq.proto" />
|
||||||
|
<None Remove="PlayerCookReq.proto" />
|
||||||
|
<None Remove="PlayerDataNotify.proto" />
|
||||||
|
<None Remove="PlayerDieType.proto" />
|
||||||
|
<None Remove="PlayerEnterDungeonRsp.proto" />
|
||||||
|
<None Remove="PlayerEnterSceneNotify.proto" />
|
||||||
|
<None Remove="PlayerLocationInfo.proto" />
|
||||||
|
<None Remove="PlayerLoginRsp.proto" />
|
||||||
|
<None Remove="PlayerLogoutReq.proto" />
|
||||||
|
<None Remove="PlayerPropChangeNotify.proto" />
|
||||||
|
<None Remove="PlayerPropNotify.proto" />
|
||||||
|
<None Remove="PlayerQuitDungeonRsp.proto" />
|
||||||
|
<None Remove="PlayerRandomCookRsp.proto" />
|
||||||
|
<None Remove="PlayerSetLanguageRsp.proto" />
|
||||||
|
<None Remove="PlayerSetPauseRsp.proto" />
|
||||||
|
<None Remove="PlayerTimeNotify.proto" />
|
||||||
|
<None Remove="PropValue.proto" />
|
||||||
|
<None Remove="QueryCurrRegionHttpRsp.proto" />
|
||||||
|
<None Remove="Quest.proto" />
|
||||||
|
<None Remove="QuestCreateEntityRsp.proto" />
|
||||||
|
<None Remove="QuestDestroyEntityReq.proto" />
|
||||||
|
<None Remove="QuestListNotify.proto" />
|
||||||
|
<None Remove="QUEST_OBJECTIVE.proto" />
|
||||||
|
<None Remove="QUEST_OBJECTIVE_DETAIL.proto" />
|
||||||
|
<None Remove="QUEST_STATE.proto" />
|
||||||
|
<None Remove="ReadMailNotify.proto" />
|
||||||
|
<None Remove="RefreshBackgroundAvatarRsp.proto" />
|
||||||
|
<None Remove="RegionSimpleInfo.proto" />
|
||||||
|
<None Remove="Reliquary.proto" />
|
||||||
|
<None Remove="ReliquaryPromoteRsp.proto" />
|
||||||
|
<None Remove="ReliquaryUpgradeRsp.proto" />
|
||||||
|
<None Remove="REMOVE_ITEM_NEW_DATA.proto" />
|
||||||
|
<None Remove="ResponseStatus.proto" />
|
||||||
|
<None Remove="Reward.proto" />
|
||||||
|
<None Remove="REWARD_ITEM.proto" />
|
||||||
|
<None Remove="ROLE_BASE_INFO.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_CHARACTER_WORK_CHARACTER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_BB.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_BB_POWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_CE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_CE_EventType.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_CT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_BOX_BRIDGE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_BOX_ROUTER_M1.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_BURN_POWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_CACHE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_CACHE_TRANSPORT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_COLLECTOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_GRID_BOX.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_HEAL_TOWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_HS_FB_PRODUCER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_MANUFACTURE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_MANUFACTURE_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_MODIFY_REGION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_CHARACTER_WORK.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_CHARACTER_WORK_CHARACTER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_OUTSIDE_RESOURCE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_OUTSIDE_RESOURCE_NODE_USE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_POWER_CONNECTION_MAP.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_POWER_CONNECTION_MAP_CONNECTION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_POWER_CONNECTION_MAP_NODE_ELEM.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_RELATION_BOARD.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OBSERVER_PAYLOAD_RET_CHECKOUT_RELATION_BOARD_CONVEYOR_ELEM.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_ADD_CONNECTION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_CACHE_TRANSPORT_ENABLE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_CACHE_TRANSPORT_TRANSFER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_DEL_CONNECTION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_DISMANTLE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_DISMANTLE_BOX_CONVEYOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_ENABLE_NODE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_GRID_BOX_INNER_MOVE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_GRID_BOX_INNER_SPLIT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_BAG_TO_CACHE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_BAG_TO_GRID_BOX.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_CACHE_TO_BAG.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_CACHE_TO_CACHE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_CACHE_TO_DEPOT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_CONVEYOR_TO_BAG.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_DEPOT_TO_CACHE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_DEPOT_TO_GRID_BOX.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_GRID_BOX_TO_BAG.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_ITEM_GRID_BOX_TO_DEPOT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_MOVE_NODE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_PLACE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_PLACE_BOX_CONVEYOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_SET_COLLECT_TARGET.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_SET_SELECT_TARGET.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_SET_TRAVEL_POLE_DEFAULT_NEXT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_OP_RET_USE_HEAL_TOWER_POINT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_PROCESSOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_PROCESSOR_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_RECT_INT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_RECYCLER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_RECYCLER_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_REPAIR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_REPAIR_BUILDING.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SKILL_BOARD_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SOIL.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SOIL_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STATISTIC_LASTDAY.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STATISTIC_LASTDAY_DAY.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STATISTIC_OPTION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STATISTIC_OTHER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STATISTIC_RECORD.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_STT_NODE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SUB_PORT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_BLACKBOARD.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_BLACKBOARD_POWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_BOX_BRIDGE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_BOX_CONVEYOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_BOX_ROUTER_M1.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_BURN_POWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_BUS_LOADER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_CACHE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_CACHE_TRANSPORT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_COLLECTOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_GRID_BOX.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_HEAL_TOWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_INVENTORY.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_POWER_POLE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_POWER_SAVE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_PRODUCER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_SELECTOR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_STABLE_POWER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_SUB_PORT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_COMPONENT_TRAVEL_POLE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_DYNAMIC_PROPERTY.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_DYNAMIC_PROPERTY_VALUE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_FORMULA_MAN.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_INTERACTIVE_OBJECT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_ITEM.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_MANUALLY_WORK.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_MANUALLY_WORK_UNIT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_MESH.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_NODE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_QUICKBAR.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_REGION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_SCENE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_SCENE_BANDWIDTH.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_SCENE_CONNECTION.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_SCENE_CONNECTION_PORT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_STT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_SYNC_TRANSFORM.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_TRADE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_TRADE_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_TRADE_ORDER.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_VECTOR2_INT.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_WORKSHOP.proto" />
|
||||||
|
<None Remove="SCD_FACTORY_WORKSHOP_MACHINE.proto" />
|
||||||
|
<None Remove="SCD_ITEM_BAG.proto" />
|
||||||
|
<None Remove="SCD_ITEM_BAG_MODIFY.proto" />
|
||||||
|
<None Remove="SCD_ITEM_DEPOT.proto" />
|
||||||
|
<None Remove="SCD_ITEM_DEPOT_MODIFY.proto" />
|
||||||
|
<None Remove="SCD_ITEM_GRID.proto" />
|
||||||
|
<None Remove="SCD_ITEM_USE_BLACKBOARD.proto" />
|
||||||
|
<None Remove="SceneAreaExploreNotify.proto" />
|
||||||
|
<None Remove="SceneAreaWeatherNotify.proto" />
|
||||||
|
<None Remove="SceneAvatarStaminaStepReq.proto" />
|
||||||
|
<None Remove="SceneCreateEntityReq.proto" />
|
||||||
|
<None Remove="SceneDestroyEntityReq.proto" />
|
||||||
|
<None Remove="SceneEntitiesMovesNotify.proto" />
|
||||||
|
<None Remove="SceneEntitiesMovesRsp.proto" />
|
||||||
|
<None Remove="SceneEntityAppearNotify.proto" />
|
||||||
|
<None Remove="SceneEntityDrownReq.proto" />
|
||||||
|
<None Remove="SceneEntityInfo.proto" />
|
||||||
|
<None Remove="SceneEntityMoveReq.proto" />
|
||||||
|
<None Remove="SceneForceLockNotify.proto" />
|
||||||
|
<None Remove="SceneGadgetInfo.proto" />
|
||||||
|
<None Remove="SceneGetAreaExplorePercentRsp.proto" />
|
||||||
|
<None Remove="SceneInitFinishRsp.proto" />
|
||||||
|
<None Remove="SceneKickPlayerReq.proto" />
|
||||||
|
<None Remove="SceneMonsterInfo.proto" />
|
||||||
|
<None Remove="ScenePlayerInfo.proto" />
|
||||||
|
<None Remove="ScenePlayerLocationNotify.proto" />
|
||||||
|
<None Remove="ScenePointUnlockNotify.proto" />
|
||||||
|
<None Remove="SceneRouteChangeInfo.proto" />
|
||||||
|
<None Remove="SceneSurfaceMaterial.proto" />
|
||||||
|
<None Remove="SceneTransToPointReq.proto" />
|
||||||
|
<None Remove="SceneWeaponInfo.proto" />
|
||||||
|
<None Remove="SCENE_CHARACTER.proto" />
|
||||||
|
<None Remove="SCENE_COLLECTION.proto" />
|
||||||
|
<None Remove="SCENE_IMPL_DUNGEON.proto" />
|
||||||
|
<None Remove="SCENE_IMPL_EMPTY.proto" />
|
||||||
|
<None Remove="SCENE_INTERACTIVE.proto" />
|
||||||
|
<None Remove="SCENE_MAP_MARK.proto" />
|
||||||
|
<None Remove="SCENE_MONSTER.proto" />
|
||||||
|
<None Remove="SCENE_NPC.proto" />
|
||||||
|
<None Remove="SCENE_OBJECT_COMMON_INFO.proto" />
|
||||||
|
<None Remove="SCENE_OBJECT_DETAIL_CONTAINER.proto" />
|
||||||
|
<None Remove="SCENE_SPAWN_INTERACTIVE_TYPE.proto" />
|
||||||
|
<None Remove="SCENE_SPAWN_MONSTER_TYPE.proto" />
|
||||||
|
<None Remove="SCENE_SUMMON.proto" />
|
||||||
|
<None Remove="SCENE_TRACK_POINT.proto" />
|
||||||
|
<None Remove="SC_ACCEPT_GUIDE_GROUP.proto" />
|
||||||
|
<None Remove="SC_ACHIEVE_COMPLETE.proto" />
|
||||||
|
<None Remove="SC_BITSET_ADD.proto" />
|
||||||
|
<None Remove="SC_BITSET_REMOVE.proto" />
|
||||||
|
<None Remove="SC_BITSET_REMOVE_ALL.proto" />
|
||||||
|
<None Remove="SC_BLOC_COMPLETED_MISSION_NUM_UPDATE.proto" />
|
||||||
|
<None Remove="SC_BLOC_SHOP_BUY.proto" />
|
||||||
|
<None Remove="SC_BLOC_SYNC_LEVEL.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_ADD_CHAR.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_SET_CURR_TEAM_INDEX.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_SET_MAX_TEAM_MEMBER_COUNT.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_SET_TEAM.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_SET_TEAM_LEADER.proto" />
|
||||||
|
<None Remove="SC_CHAR_BAG_SET_TEAM_NAME.proto" />
|
||||||
|
<None Remove="SC_CHAR_BREAK.proto" />
|
||||||
|
<None Remove="SC_CHAR_GAIN_EXP_TOAST.proto" />
|
||||||
|
<None Remove="SC_CHAR_LEVEL_UP.proto" />
|
||||||
|
<None Remove="SC_CHAR_SET_NORMAL_SKILL.proto" />
|
||||||
|
<None Remove="SC_CHAR_SET_TEAM_SKILL.proto" />
|
||||||
|
<None Remove="SC_CHAR_SKILL_LEVEL_UP.proto" />
|
||||||
|
<None Remove="SC_CHAR_SYNC_LEVEL_EXP.proto" />
|
||||||
|
<None Remove="SC_CHAR_SYNC_STATUS.proto" />
|
||||||
|
<None Remove="SC_CHAR_UNLOCK_SKILL.proto" />
|
||||||
|
<None Remove="SC_COMPLETE_GUIDE_GROUP.proto" />
|
||||||
|
<None Remove="SC_COMPLETE_GUIDE_GROUP_KEY_STEP.proto" />
|
||||||
|
<None Remove="SC_DEL_MAIL_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_DUNGEON_REWARD.proto" />
|
||||||
|
<None Remove="SC_ENTER_DUNGEON.proto" />
|
||||||
|
<None Remove="SC_ENTER_SCENE_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_EQUIP_PUTOFF.proto" />
|
||||||
|
<None Remove="SC_EQUIP_PUTON.proto" />
|
||||||
|
<None Remove="SC_FACTORY_COMMON_RET.proto" />
|
||||||
|
<None Remove="SC_FACTORY_HS.proto" />
|
||||||
|
<None Remove="SC_FACTORY_HS_SYNC.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MANUALLY_WORK_CANCEL.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MANUFACTURE_CANCEL.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MANUFACTURE_SETTLE.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MANUFACTURE_START.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_CHARACTER_WORK.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_CONTEXT.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_FORMULA_MAN.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_MANUALLY_WORK.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_MANUFACTURE.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_PROCESSOR.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_QUICKBAR.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_RECYCLER.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_REGION_COMPONENTS.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_REGION_NODES.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_REGION_SCENE.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_REPAIR.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_SKILL_BOARD.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_SOIL.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_STATISTIC.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_STT.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_TRADE.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_VISIBLE_FORMULA.proto" />
|
||||||
|
<None Remove="SC_FACTORY_MODIFY_WORKSHOP.proto" />
|
||||||
|
<None Remove="SC_FACTORY_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_FACTORY_OBSERVER_RET.proto" />
|
||||||
|
<None Remove="SC_FACTORY_OP_RET.proto" />
|
||||||
|
<None Remove="SC_FACTORY_PROCESSOR_RET.proto" />
|
||||||
|
<None Remove="SC_FACTORY_RECYCLER_COMMIT_MATERIAL.proto" />
|
||||||
|
<None Remove="SC_FACTORY_RECYCLER_FETCH_PRODUCT.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SOIL_CANCEL.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SOIL_HARVEST.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SOIL_PLANT.proto" />
|
||||||
|
<None Remove="SC_FACTORY_STATISTIC_REQUIRE.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC_CHARACTER_WORK.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC_CONTEXT.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC_REGION_NODES.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC_SKILL_BOARD.proto" />
|
||||||
|
<None Remove="SC_FACTORY_SYNC_STATISTIC.proto" />
|
||||||
|
<None Remove="SC_FACTORY_TRADE_CASH_ORDER.proto" />
|
||||||
|
<None Remove="SC_FINISH_DIALOG.proto" />
|
||||||
|
<None Remove="SC_FLUSH_SYNC.proto" />
|
||||||
|
<None Remove="SC_GET_MAIL.proto" />
|
||||||
|
<None Remove="SC_GET_MAIL_ATTACHMENT.proto" />
|
||||||
|
<None Remove="SC_GM_COMMAND.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_BAG_TO_FACTORY_DEPOT.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SET_ITEM_LOCK.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SET_QUICK_BAR.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SET_QUICK_BAR_POS.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SYNC.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SYNC_MODIFY.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_SYNC_QUICK_BAR.proto" />
|
||||||
|
<None Remove="SC_ITEM_BAG_USE_ITEM.proto" />
|
||||||
|
<None Remove="SC_LEAVE_DUNGEON.proto" />
|
||||||
|
<None Remove="SC_LEAVE_SCENE_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_LOGIN.proto" />
|
||||||
|
<None Remove="SC_MISSION_DELETED.proto" />
|
||||||
|
<None Remove="SC_MISSION_FAILED.proto" />
|
||||||
|
<None Remove="SC_MISSION_STATE_UPDATE.proto" />
|
||||||
|
<None Remove="SC_MOVE_OBJECT_MOVE.proto" />
|
||||||
|
<None Remove="SC_NEW_MAIL_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_NEW_NOTICE_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_NTF_CODE.proto" />
|
||||||
|
<None Remove="SC_NTF_ERROR_CODE.proto" />
|
||||||
|
<None Remove="SC_OBJECT_ENTER_VIEW.proto" />
|
||||||
|
<None Remove="SC_OBJECT_LEAVE_VIEW.proto" />
|
||||||
|
<None Remove="SC_PING.proto" />
|
||||||
|
<None Remove="SC_QUEST_FAILED.proto" />
|
||||||
|
<None Remove="SC_QUEST_OBJECTIVES_UPDATE.proto" />
|
||||||
|
<None Remove="SC_QUEST_STATE_UPDATE.proto" />
|
||||||
|
<None Remove="SC_READ_MAIL.proto" />
|
||||||
|
<None Remove="SC_RECONNECT_FULL.proto" />
|
||||||
|
<None Remove="SC_RECONNECT_INCR.proto" />
|
||||||
|
<None Remove="SC_REMOVE_ITEM_NEW_TAGS.proto" />
|
||||||
|
<None Remove="SC_RESTART_DUNGEON.proto" />
|
||||||
|
<None Remove="SC_REWARD_DROP_MONEY_TOAST.proto" />
|
||||||
|
<None Remove="SC_REWARD_TOAST_BEGIN.proto" />
|
||||||
|
<None Remove="SC_REWARD_TOAST_END.proto" />
|
||||||
|
<None Remove="SC_REWARD_TO_SCENE_BEGIN.proto" />
|
||||||
|
<None Remove="SC_REWARD_TO_SCENE_END.proto" />
|
||||||
|
<None Remove="SC_ROLL_BLOC_MISSION.proto" />
|
||||||
|
<None Remove="SC_SCENE_COLLECTION_MODIFY.proto" />
|
||||||
|
<None Remove="SC_SCENE_COLLECTION_SYNC.proto" />
|
||||||
|
<None Remove="SC_SCENE_CREATE_ENTITY.proto" />
|
||||||
|
<None Remove="SC_SCENE_DESTROY_ENTITY.proto" />
|
||||||
|
<None Remove="SC_SCENE_INTERACTIVE_EVENT_TRIGGER.proto" />
|
||||||
|
<None Remove="SC_SCENE_LEVEL_SCRIPT_EVENT_TRIGGER.proto" />
|
||||||
|
<None Remove="SC_SCENE_LEVEL_SCRIPT_RESET_BEGIN.proto" />
|
||||||
|
<None Remove="SC_SCENE_LEVEL_SCRIPT_RESET_END.proto" />
|
||||||
|
<None Remove="SC_SCENE_LEVEL_SCRIPT_STATE_NOTIFY.proto" />
|
||||||
|
<None Remove="SC_SCENE_MAP_MARK_MODIFY.proto" />
|
||||||
|
<None Remove="SC_SCENE_MAP_MARK_SYNC.proto" />
|
||||||
|
<None Remove="SC_SCENE_QUERY_ENTITY_EXIST.proto" />
|
||||||
|
<None Remove="SC_SCENE_QUERY_INTERACTIVE_PROPERTY.proto" />
|
||||||
|
<None Remove="SC_SCENE_RESET_ENTITY.proto" />
|
||||||
|
<None Remove="SC_SCENE_REVIVAL.proto" />
|
||||||
|
<None Remove="SC_SCENE_REVIVAL_MODE_MODIFY.proto" />
|
||||||
|
<None Remove="SC_SCENE_SET_BATTLE.proto" />
|
||||||
|
<None Remove="SC_SCENE_SET_LAST_RECORD_CAMPID.proto" />
|
||||||
|
<None Remove="SC_SCENE_SET_SAFE_ZONE.proto" />
|
||||||
|
<None Remove="SC_SCENE_SET_TRACK_POINT.proto" />
|
||||||
|
<None Remove="SC_SCENE_SET_VAR.proto" />
|
||||||
|
<None Remove="SC_SCENE_SUBMIT_ETHER.proto" />
|
||||||
|
<None Remove="SC_SCENE_SUBMIT_ITEM.proto" />
|
||||||
|
<None Remove="SC_SCENE_TELEPORT.proto" />
|
||||||
|
<None Remove="SC_SCENE_UNLOCK_AREA.proto" />
|
||||||
|
<None Remove="SC_SCENE_UPDATE_INTERACTIVE_PROPERTY.proto" />
|
||||||
|
<None Remove="SC_SCENE_UPDATE_LEVEL_SCRIPT_PROPERTY.proto" />
|
||||||
|
<None Remove="SC_SELF_SCENE_INFO.proto" />
|
||||||
|
<None Remove="SC_START_DUNGEON_CHALLENGE.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_BITSET.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_BLOC.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_DIALOG.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_GUIDE.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_MAIL.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_MISSION.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_ROLE_SCENE.proto" />
|
||||||
|
<None Remove="SC_SYNC_ALL_UNLOCK.proto" />
|
||||||
|
<None Remove="SC_SYNC_ATTR.proto" />
|
||||||
|
<None Remove="SC_SYNC_BASE_DATA.proto" />
|
||||||
|
<None Remove="SC_SYNC_BLOC_MISSION_INFO.proto" />
|
||||||
|
<None Remove="SC_SYNC_CHAR_BAG_INFO.proto" />
|
||||||
|
<None Remove="SC_SYNC_DUNGEON_CHALLENGE_STATUS.proto" />
|
||||||
|
<None Remove="SC_SYNC_DUNGEON_PASS_STATUS.proto" />
|
||||||
|
<None Remove="SC_SYNC_EXTRA_ATTACHMENT_ITEM.proto" />
|
||||||
|
<None Remove="SC_SYNC_FULL_DUNGEON_STATUS.proto" />
|
||||||
|
<None Remove="SC_SYNC_GAME_MODE.proto" />
|
||||||
|
<None Remove="SC_SYNC_STAMINA.proto" />
|
||||||
|
<None Remove="SC_SYNC_STATISTIC.proto" />
|
||||||
|
<None Remove="SC_SYNC_WALLET.proto" />
|
||||||
|
<None Remove="SC_SYNC_WIKI_PIN.proto" />
|
||||||
|
<None Remove="SC_TRACK_MISSION_CHANGE.proto" />
|
||||||
|
<None Remove="SC_UNLOCK_SYSTEM.proto" />
|
||||||
|
<None Remove="SC_WALLET_SYNC_MONEY.proto" />
|
||||||
|
<None Remove="SC_WEAPON_ADD_EXP.proto" />
|
||||||
|
<None Remove="SC_WEAPON_ATTACH_GEM.proto" />
|
||||||
|
<None Remove="SC_WEAPON_BREAKTHROUGH.proto" />
|
||||||
|
<None Remove="SC_WEAPON_DETACH_GEM.proto" />
|
||||||
|
<None Remove="SC_WEAPON_PUTON.proto" />
|
||||||
|
<None Remove="SDComponentBoxConveyor.proto" />
|
||||||
|
<None Remove="SDComponentBoxRouter.proto" />
|
||||||
|
<None Remove="SDComponentBus.proto" />
|
||||||
|
<None Remove="SDComponentBusLoader.proto" />
|
||||||
|
<None Remove="SDComponentBusUnloader.proto" />
|
||||||
|
<None Remove="SDComponentCache.proto" />
|
||||||
|
<None Remove="SDComponentCollector.proto" />
|
||||||
|
<None Remove="SDComponentFormulaMan.proto" />
|
||||||
|
<None Remove="SDComponentProducer.proto" />
|
||||||
|
<None Remove="SDComponentSelector.proto" />
|
||||||
|
<None Remove="SDNodeBoxConveyor.proto" />
|
||||||
|
<None Remove="SDNodeBoxRouter.proto" />
|
||||||
|
<None Remove="SDNodeBus.proto" />
|
||||||
|
<None Remove="SDNodeBusLoader.proto" />
|
||||||
|
<None Remove="SDNodeBusUnloader.proto" />
|
||||||
|
<None Remove="SDNodeCollector.proto" />
|
||||||
|
<None Remove="SDNodeProducer.proto" />
|
||||||
|
<None Remove="SDShape.proto" />
|
||||||
|
<None Remove="SDTemplate.proto" />
|
||||||
|
<None Remove="SealBattleEndNotify.proto" />
|
||||||
|
<None Remove="SealBattleType.proto" />
|
||||||
|
<None Remove="SeeMonsterRsp.proto" />
|
||||||
|
<None Remove="SelectWorktopOptionRsp.proto" />
|
||||||
|
<None Remove="SEND_MAIL_DEF.proto" />
|
||||||
|
<None Remove="ServerLogNotify.proto" />
|
||||||
|
<None Remove="ServerTimeNotify.proto" />
|
||||||
|
<None Remove="SetOpenStateReq.proto" />
|
||||||
|
<None Remove="SetPlayerBornDataReq.proto" />
|
||||||
|
<None Remove="SetPlayerNameReq.proto" />
|
||||||
|
<None Remove="SetPlayerPropReq.proto" />
|
||||||
|
<None Remove="SetSceneWeatherAreaReq.proto" />
|
||||||
|
<None Remove="SetUpAvatarTeamReq.proto" />
|
||||||
|
<None Remove="ShapeType.proto" />
|
||||||
|
<None Remove="Shop.proto" />
|
||||||
|
<None Remove="SHOP_INFO.proto" />
|
||||||
|
<None Remove="ShowMessageNotify.proto" />
|
||||||
|
<None Remove="SKILL_INFO.proto" />
|
||||||
|
<None Remove="SKILL_LEVEL_INFO.proto" />
|
||||||
|
<None Remove="SpringUseRsp.proto" />
|
||||||
|
<None Remove="SP_INTERACTIVE_OP_TYPE.proto" />
|
||||||
|
<None Remove="STATISTIC_RECORD.proto" />
|
||||||
|
<None Remove="StoreItemChangeNotify.proto" />
|
||||||
|
<None Remove="StoreType.proto" />
|
||||||
|
<None Remove="SUBMIT_ITEM.proto" />
|
||||||
|
<None Remove="SUBMIT_SOURCE_PARAM_INTERACTIVE.proto" />
|
||||||
|
<None Remove="SUBMIT_SOURCE_PARAM_MISSION.proto" />
|
||||||
|
<None Remove="SUBMIT_SOURCE_TYPE.proto" />
|
||||||
|
<None Remove="SubPort.proto" />
|
||||||
|
<None Remove="SvrMsgId.proto" />
|
||||||
|
<None Remove="TakeCompoundOutputRsp.proto" />
|
||||||
|
<None Remove="TakeoffEquipRsp.proto" />
|
||||||
|
<None Remove="TransmitReason.proto" />
|
||||||
|
<None Remove="TriggerCreateGadgetToEquipPartNotify.proto" />
|
||||||
|
<None Remove="UnlockAvatarTalentRsp.proto" />
|
||||||
|
<None Remove="UnlockTransPointRsp.proto" />
|
||||||
|
<None Remove="UseItemReq.proto" />
|
||||||
|
<None Remove="Vector.proto" />
|
||||||
|
<None Remove="Vector2.proto" />
|
||||||
|
<None Remove="Version.proto" />
|
||||||
|
<None Remove="VisionType.proto" />
|
||||||
|
<None Remove="WeaponAwakenReq.proto" />
|
||||||
|
<None Remove="WeaponPromoteReq.proto" />
|
||||||
|
<None Remove="WeaponUpgradeReq.proto" />
|
||||||
|
<None Remove="WEAPON_DATA.proto" />
|
||||||
|
<None Remove="WearEquipReq.proto" />
|
||||||
|
<None Remove="WeatherInfo.proto" />
|
||||||
|
<None Remove="WIKI_PIN_ENUM.proto" />
|
||||||
|
<None Remove="WorktopOptionNotify.proto" />
|
||||||
|
<None Remove="WorldPlayerReviveReq.proto" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
200303
Campofinale.Protocol/Campofinale.cs
Normal file
200303
Campofinale.Protocol/Campofinale.cs
Normal file
File diff suppressed because it is too large
Load Diff
329
Campofinale.Protocol/CsMsgId.cs
Normal file
329
Campofinale.Protocol/CsMsgId.cs
Normal file
@ -0,0 +1,329 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Protocol
|
||||||
|
{
|
||||||
|
public enum CsMsgId : int
|
||||||
|
{
|
||||||
|
CsMessageBegin = 0,
|
||||||
|
CsLogin = 1,
|
||||||
|
CsCreateRole = 2,
|
||||||
|
CsLogout = 3,
|
||||||
|
CsGmCommand = 4,
|
||||||
|
CsPing = 5,
|
||||||
|
CsFlushSync = 6,
|
||||||
|
CsSetName = 7,
|
||||||
|
CsSetGender = 8,
|
||||||
|
CsCheckName = 9,
|
||||||
|
CsCheckSensitive = 10,
|
||||||
|
CsAchieveBegin = 20,
|
||||||
|
CsAchieveComplete = 21,
|
||||||
|
CsAchieveTakeReward = 22,
|
||||||
|
CsAchieveEnd = 29,
|
||||||
|
CsCharBagBegin = 30,
|
||||||
|
CsCharBagTeamBegin = 31,
|
||||||
|
CsCharBagSetTeam = 32,
|
||||||
|
CsCharBagSetCurrTeamIndex = 33,
|
||||||
|
CsCharBagSetTeamName = 34,
|
||||||
|
CsCharBagSetTeamLeader = 35,
|
||||||
|
CsCharBagTeamChangeFinish = 36,
|
||||||
|
CsCharBagTeamEnd = 37,
|
||||||
|
CsCharBagEnd = 39,
|
||||||
|
CsCharBegin = 40,
|
||||||
|
CsCharLevelUp = 41,
|
||||||
|
CsCharSetNormalSkill = 43,
|
||||||
|
CsCharSkillLevelUp = 45,
|
||||||
|
CsCharSetTeamSkill = 46,
|
||||||
|
CsCharPotentialUnlock = 47,
|
||||||
|
CsCharEnd = 49,
|
||||||
|
CsEquipBegin = 50,
|
||||||
|
CsEquipPuton = 51,
|
||||||
|
CsEquipPutoff = 52,
|
||||||
|
CsEquipMedicineModify = 53,
|
||||||
|
CsEquipRecycle = 54,
|
||||||
|
CsEquipEnhance = 55,
|
||||||
|
CsEquipProduce = 57,
|
||||||
|
CsEquipEnd = 59,
|
||||||
|
CsSceneBegin = 80,
|
||||||
|
CsEnterScene = 81,
|
||||||
|
CsMoveObjectMove = 82,
|
||||||
|
CsSceneSetLastRecordCampid = 83,
|
||||||
|
CsSceneInteractiveEventTrigger = 84,
|
||||||
|
CsSceneSetVar = 85,
|
||||||
|
CsSceneRest = 86,
|
||||||
|
CsSceneLoadFinish = 88,
|
||||||
|
CsSceneSetSafeZone = 95,
|
||||||
|
CsSceneQueryEntityExist = 96,
|
||||||
|
CsSceneQueryInteractiveProperty = 97,
|
||||||
|
CsSceneSetTrackPoint = 99,
|
||||||
|
CsSceneInteractTree = 100,
|
||||||
|
CsSceneStaticMapMarkUpdate = 101,
|
||||||
|
CsSceneTeleport = 103,
|
||||||
|
CsSceneMoveStateSet = 104,
|
||||||
|
CsSceneSubmitItem = 105,
|
||||||
|
CsSceneSubmitEther = 106,
|
||||||
|
CsSceneSetLevelScriptActive = 107,
|
||||||
|
CsSceneLevelScriptEventTrigger = 109,
|
||||||
|
CsSceneCommitLevelScriptCacheStep = 110,
|
||||||
|
CsSceneRepatriate = 115,
|
||||||
|
CsSceneInteractSpInteractive = 116,
|
||||||
|
CsSceneSetLastSafeZone = 117,
|
||||||
|
CsSceneSetBattle = 118,
|
||||||
|
CsSceneRevival = 119,
|
||||||
|
CsSceneSetLevelScriptStart = 120,
|
||||||
|
CsSceneMonsterSpawnerBeginWave = 121,
|
||||||
|
CsSceneSpawnSummon = 122,
|
||||||
|
CsSceneLeavePlane = 123,
|
||||||
|
CsSceneGradeModify = 124,
|
||||||
|
CsSceneUpdateScriptTaskProgress = 125,
|
||||||
|
CsSceneTeleportFinish = 126,
|
||||||
|
CsSceneSetStorySafeZone = 127,
|
||||||
|
CsSceneSubmitRecycle = 128,
|
||||||
|
CsSceneEnd = 199,
|
||||||
|
CsFactoryBegin = 200,
|
||||||
|
CsFactorySttUnlockNode = 201,
|
||||||
|
CsFactorySttUnlockLayer = 202,
|
||||||
|
CsFactoryManuallyWorkExec = 211,
|
||||||
|
CsFactoryProductManualUnlock = 212,
|
||||||
|
CsFactoryQuickbarSetOne = 215,
|
||||||
|
CsFactoryQuickbarMoveOne = 216,
|
||||||
|
CsFactorySoilReclaim = 217,
|
||||||
|
CsFactorySoilWater = 218,
|
||||||
|
CsFactorySoilCancel = 219,
|
||||||
|
CsFactorySoilHarvest = 220,
|
||||||
|
CsFactorySoilFarmlandLevelUp = 221,
|
||||||
|
CsFactoryHubWorkshopMake = 222,
|
||||||
|
CsFactoryHubTransportRouteSet = 223,
|
||||||
|
CsFactoryHubTransportRouteReset = 224,
|
||||||
|
CsFactoryHubTransportRouteRestart = 225,
|
||||||
|
CsFactoryHsFb = 232,
|
||||||
|
CsFactoryStatisticSetBookmarkItemIds = 234,
|
||||||
|
CsFactoryStatisticRequire = 235,
|
||||||
|
CsFactoryPinSet = 236,
|
||||||
|
CsFactoryOp = 251,
|
||||||
|
CsFactoryObserverOp = 268,
|
||||||
|
CsFactoryEnd = 269,
|
||||||
|
CsWeaponBegin = 270,
|
||||||
|
CsWeaponPuton = 271,
|
||||||
|
CsWeaponBreakthrough = 273,
|
||||||
|
CsWeaponAddExp = 274,
|
||||||
|
CsWeaponAttachGem = 275,
|
||||||
|
CsWeaponDetachGem = 276,
|
||||||
|
CsWeaponRefineUpgrade = 277,
|
||||||
|
CsWeaponEnd = 279,
|
||||||
|
CsWikiBegin = 290,
|
||||||
|
CsUnlockWiki = 291,
|
||||||
|
CsMarkWikiRead = 292,
|
||||||
|
CsWikiEnd = 299,
|
||||||
|
CsMissionBegin = 310,
|
||||||
|
CsFailMission = 311,
|
||||||
|
CsTrackMission = 313,
|
||||||
|
CsStopTrackingMission = 314,
|
||||||
|
CsUpdateQuestObjective = 315,
|
||||||
|
CsAcceptMission = 316,
|
||||||
|
CsRollBlocMission = 317,
|
||||||
|
CsMissionEventTrigger = 318,
|
||||||
|
CsMissionClientTriggerDone = 319,
|
||||||
|
CsSetNewMissionTagDone = 320,
|
||||||
|
CsMissionEnd = 329,
|
||||||
|
CsGuideBegin = 330,
|
||||||
|
CsCompleteGuideGroupKeyStep = 331,
|
||||||
|
CsCompleteGuideGroup = 332,
|
||||||
|
CsGuideEnd = 339,
|
||||||
|
CsDialogBegin = 340,
|
||||||
|
CsFinishDialog = 341,
|
||||||
|
CsDialogEnd = 349,
|
||||||
|
CsBlocBegin = 350,
|
||||||
|
CsBlocTakeLevelReward = 351,
|
||||||
|
CsBlocShopBuy = 352,
|
||||||
|
CsBlocEnd = 360,
|
||||||
|
CsDungeonBegin = 370,
|
||||||
|
CsEnterDungeon = 371,
|
||||||
|
CsRestartDungeon = 372,
|
||||||
|
CsLeaveDungeon = 373,
|
||||||
|
CsDungeonRecoverAp = 375,
|
||||||
|
CsDungeonTouchEntrance = 377,
|
||||||
|
CsDungeonEnd = 378,
|
||||||
|
CsEnterTrainDungeon = 379,
|
||||||
|
CsGameMechanicsBegin = 380,
|
||||||
|
CsGameMechanicsReqActive = 381,
|
||||||
|
CsGameMechanicsReqReward = 382,
|
||||||
|
CsGameMechanicsNtfInstPrepareFinish = 383,
|
||||||
|
CsGameMechanicsEnd = 399,
|
||||||
|
CsMailBegin = 400,
|
||||||
|
CsGetMail = 401,
|
||||||
|
CsReadMail = 402,
|
||||||
|
CsDeleteMail = 403,
|
||||||
|
CsDeleteAllMail = 404,
|
||||||
|
CsGetMailAttachment = 405,
|
||||||
|
CsGetAllMailAttachment = 406,
|
||||||
|
CsMarkStarMail = 407,
|
||||||
|
CsMailEnd = 419,
|
||||||
|
CsRedDotBegin = 430,
|
||||||
|
CsRemoveItemNewTags = 431,
|
||||||
|
CsRedDotReadFormula = 432,
|
||||||
|
CsRedDotReadCharDoc = 433,
|
||||||
|
CsRedDotReadCharVoice = 434,
|
||||||
|
CsRedDotReadEquipFormula = 435,
|
||||||
|
CsRedDotEnd = 440,
|
||||||
|
CsPrtsBegin = 441,
|
||||||
|
CsPrtsMarkRead = 442,
|
||||||
|
CsPrtsMarkTerminalRead = 443,
|
||||||
|
CsPrtsRichContentRead = 444,
|
||||||
|
CsPrtsFinishInvestigate = 445,
|
||||||
|
CsPrtsEnd = 449,
|
||||||
|
CsBitsetBegin = 480,
|
||||||
|
CsBitsetAdd = 481,
|
||||||
|
CsBitsetRemove = 482,
|
||||||
|
CsBitsetRemoveAll = 483,
|
||||||
|
CsBitsetEnd = 499,
|
||||||
|
CsMergeMsg = 500,
|
||||||
|
CsPayBegin = 510,
|
||||||
|
CsCreateOrder = 511,
|
||||||
|
CsPayEnd = 529,
|
||||||
|
CsFriendBegin = 530,
|
||||||
|
CsFriendRequestSubmit = 531,
|
||||||
|
CsFriendRequestReject = 532,
|
||||||
|
CsFriendRequestAccept = 533,
|
||||||
|
CsFriendDelete = 534,
|
||||||
|
CsFriendSearchName = 535,
|
||||||
|
CsFriendRequestListSync = 536,
|
||||||
|
CsFriendListSync = 537,
|
||||||
|
CsFriendEnd = 570,
|
||||||
|
CsWalletBegin = 600,
|
||||||
|
CsMoneyChange = 601,
|
||||||
|
CsWalletEnd = 630,
|
||||||
|
CsGameVarBegin = 631,
|
||||||
|
CsUpdateClientGameVar = 632,
|
||||||
|
CsGameVarEnd = 640,
|
||||||
|
CsMiniGameBegin = 641,
|
||||||
|
CsCompleteMiniGame = 642,
|
||||||
|
CsMiniGameEnd = 650,
|
||||||
|
CsRpgDungeonBegin = 651,
|
||||||
|
CsRpgDungeonBuy = 652,
|
||||||
|
CsRpgDungeonSell = 653,
|
||||||
|
CsRpgDungeonEquipPuton = 654,
|
||||||
|
CsRpgDungeonEquipPutoff = 655,
|
||||||
|
CsRpgDungeonPickLvAbility = 656,
|
||||||
|
CsRpgDungeonTimeStop = 657,
|
||||||
|
CsRpgDungeonAbilityChange = 658,
|
||||||
|
CsRpgDungeonEnd = 700,
|
||||||
|
CsGemBegin = 801,
|
||||||
|
CsGemRecast = 802,
|
||||||
|
CsGemEnd = 820,
|
||||||
|
CsSnsBegin = 701,
|
||||||
|
CsSnsGetList = 702,
|
||||||
|
CsSnsMomentOption = 703,
|
||||||
|
CsSnsChatDialogOption = 704,
|
||||||
|
CsSnsMomentRead = 705,
|
||||||
|
CsSnsFinishDialog = 706,
|
||||||
|
CsSnsReadDialog = 707,
|
||||||
|
CsSnsEnd = 730,
|
||||||
|
CsSpaceshipBegin = 751,
|
||||||
|
CsSpaceshipBuildRoom = 752,
|
||||||
|
CsSpaceshipLevelUpRoom = 753,
|
||||||
|
CsSpaceshipStationChar = 754,
|
||||||
|
CsSpaceshipStationCharChangeWorkState = 755,
|
||||||
|
CsSpaceshipPresentGiftToChar = 756,
|
||||||
|
CsSpaceshipRecvGiftFromChar = 757,
|
||||||
|
CsSpaceshipManufacturingBegin = 771,
|
||||||
|
CsSpaceshipManufacturingStationStart = 772,
|
||||||
|
CsSpaceshipManufacturingStationCollect = 775,
|
||||||
|
CsSpaceshipManufacturingStationCancel = 776,
|
||||||
|
CsSpaceshipManufacturingStationChangeOrder = 777,
|
||||||
|
CsSpaceshipManufacturingEnd = 785,
|
||||||
|
CsSpaceshipGrowCabinBegin = 786,
|
||||||
|
CsSpaceshipGrowCabinBreed = 787,
|
||||||
|
CsSpaceshipGrowCabinSow = 788,
|
||||||
|
CsSpaceshipGrowCabinHarvest = 789,
|
||||||
|
CsSpaceshipGrowCabinCancel = 790,
|
||||||
|
CsSpaceshipGrowCabinClearPreviewRecipe = 791,
|
||||||
|
CsSpaceshipGrowCabinEnd = 799,
|
||||||
|
CsSpaceshipEnd = 800,
|
||||||
|
CsTdBegin = 821,
|
||||||
|
CsTdGetTdList = 822,
|
||||||
|
CsTdStart = 823,
|
||||||
|
CsTdLeave = 825,
|
||||||
|
CsTdBuyBuilding = 826,
|
||||||
|
CsTdPickDropItem = 827,
|
||||||
|
CsTdDropExpired = 828,
|
||||||
|
CsTdEnd = 899,
|
||||||
|
CsBuffBegin = 900,
|
||||||
|
CsBattleOp = 901,
|
||||||
|
CsDevClearBattleInfo = 902,
|
||||||
|
CsBuffEnd = 950,
|
||||||
|
CsSkillBegin = 960,
|
||||||
|
CsCastSkill = 961,
|
||||||
|
CsCastSkillEnd = 962,
|
||||||
|
CsCastSkillEffect = 963,
|
||||||
|
CsSkillEnd = 999,
|
||||||
|
CsItemBagBegin = 1000,
|
||||||
|
CsItemBagTidyInBag = 1001,
|
||||||
|
CsItemBagMoveInBag = 1002,
|
||||||
|
CsItemBagSplitInBag = 1003,
|
||||||
|
CsItemBagFactoryDepotToBag = 1004,
|
||||||
|
CsItemBagBagToFactoryDepot = 1005,
|
||||||
|
CsItemBagFactoryDepotToBagGrid = 1006,
|
||||||
|
CsItemBagUseItem = 1007,
|
||||||
|
CsItemBagSetQuickBar = 1008,
|
||||||
|
CsItemBagSetQuickBarPos = 1009,
|
||||||
|
CsItemBagSetItemLock = 1010,
|
||||||
|
CsItemBagAbandonInBag = 1011,
|
||||||
|
CsItemBagDestroyInDepot = 1012,
|
||||||
|
CsItemBagDestroyInFactoryDepot = 1013,
|
||||||
|
CsItemBagDumpBottleInBag = 1014,
|
||||||
|
CsItemBagDumpBottleInFactoryDepot = 1015,
|
||||||
|
CsItemBagTakeoutLostAndFound = 1031,
|
||||||
|
CsItemBagUseItemCase = 1032,
|
||||||
|
CsItemBagChgSpaceshipChapter = 1033,
|
||||||
|
CsItemBagEnd = 1049,
|
||||||
|
CsSettlementBegin = 1050,
|
||||||
|
CsSettlementSelectRequire = 1051,
|
||||||
|
CsSettlementSetOfficer = 1052,
|
||||||
|
CsSettlementSetSubmitMode = 1053,
|
||||||
|
CsSettlementSubmitRequire = 1054,
|
||||||
|
CsSettlementEnd = 1099,
|
||||||
|
CsShopBegin = 1100,
|
||||||
|
CsShopBuy = 1111,
|
||||||
|
CsShopSwapMoney = 1112,
|
||||||
|
CsShopEnd = 1149,
|
||||||
|
CsAdventureBegin = 1150,
|
||||||
|
CsAdventureTakeRewardAll = 1151,
|
||||||
|
CsAdventureEnd = 1179,
|
||||||
|
CsAdventureBookBegin = 1250,
|
||||||
|
CsTakeAllAdventureTaskReward = 1251,
|
||||||
|
CsTakeAdventureTaskReward = 1252,
|
||||||
|
CsTakeAdventureBookStageReward = 1253,
|
||||||
|
CsAdventureBookEnd = 1299,
|
||||||
|
CsTalentBegin = 1300,
|
||||||
|
CsCharUnlockTalentNode = 1301,
|
||||||
|
CsTalentEnd = 1329,
|
||||||
|
CsRacingDungeonBegin = 1330,
|
||||||
|
CsRacingDungeonBattlePassReceiveReward = 1332,
|
||||||
|
CsRacingDungeonGetBattlePass = 1333,
|
||||||
|
CsRacingDungeonGetAchievement = 1334,
|
||||||
|
CsRacingDungeonAchievementReceiveReward = 1335,
|
||||||
|
CsRacingDungeonLeave = 1336,
|
||||||
|
CsRacingDungeonUpdateBattleInfo = 1337,
|
||||||
|
CsRacingDungeonEnd = 1400,
|
||||||
|
CsTrialCharacterBegin = 1401,
|
||||||
|
CsUseTrialCharacterEquipMedicine = 1402,
|
||||||
|
CsTrialCharacterEnd = 1403,
|
||||||
|
CsGachaBegin = 1431,
|
||||||
|
CsGachaSinglePullReq = 1432,
|
||||||
|
CsGachaTenPullReq = 1433,
|
||||||
|
CsGachaEnd = 1450,
|
||||||
|
CsGameTimeFreezeBegin = 1451,
|
||||||
|
CsGameTimeFreezeStartReq = 1452,
|
||||||
|
CsGameTimeFreezeEndReq = 1453,
|
||||||
|
CsGameTimeFreezeEnd = 1460,
|
||||||
|
CsActivityBegin = 1461,
|
||||||
|
CsDailyCheckin = 1471,
|
||||||
|
CsActivityEnd = 1510,
|
||||||
|
CsMessageEnd = 4095,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
401
Campofinale.Protocol/ScMsgId.cs
Normal file
401
Campofinale.Protocol/ScMsgId.cs
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Protocol
|
||||||
|
{
|
||||||
|
public enum ScMsgId : int
|
||||||
|
{
|
||||||
|
ScMessageBegin = 0,
|
||||||
|
ScLogin = 1,
|
||||||
|
ScSyncBaseData = 2,
|
||||||
|
ScNtfErrorCode = 3,
|
||||||
|
ScGmCommand = 4,
|
||||||
|
ScPing = 5,
|
||||||
|
ScReconnectIncr = 6,
|
||||||
|
ScReconnectFull = 7,
|
||||||
|
ScFlushSync = 8,
|
||||||
|
ScNtfCode = 9,
|
||||||
|
ScSetName = 10,
|
||||||
|
ScSetGender = 11,
|
||||||
|
ScCheckName = 12,
|
||||||
|
ScCheckSensitive = 13,
|
||||||
|
ScSyncFullDataEnd = 14,//
|
||||||
|
ScAchieveComplete = 15,
|
||||||
|
ScSyncAllRoleScene = 20,//
|
||||||
|
ScObjectEnterView = 21,
|
||||||
|
ScObjectLeaveView = 22,
|
||||||
|
ScMoveObjectMove = 23,
|
||||||
|
ScEnterSceneNotify = 24,
|
||||||
|
ScSelfSceneInfo = 25,
|
||||||
|
ScLeaveSceneNotify = 26,
|
||||||
|
ScSceneSetLastRecordCampid = 27,
|
||||||
|
ScSceneUpdateInteractiveProperty = 28,
|
||||||
|
ScSceneSetVar = 29,
|
||||||
|
ScSceneRevival = 30,
|
||||||
|
ScSceneCreateEntity = 31,
|
||||||
|
ScSceneDestroyEntity = 32,
|
||||||
|
ScSceneSetSafeZone = 35,
|
||||||
|
ScSceneQueryEntityExist = 36,
|
||||||
|
ScSceneLevelScriptStateNotify = 37,
|
||||||
|
ScSceneQueryInteractiveProperty = 38,
|
||||||
|
ScSceneUnlockArea = 39,
|
||||||
|
ScSceneSetTrackPoint = 40,
|
||||||
|
ScSceneCollectionSync = 42, //
|
||||||
|
ScSceneCollectionModify = 43,
|
||||||
|
ScSceneMapMarkSync = 44,//
|
||||||
|
ScSceneStaticMapMarkModify = 45,
|
||||||
|
ScSceneTeleport = 46,
|
||||||
|
ScSceneSubmitItem = 47,
|
||||||
|
ScSceneSubmitEther = 48,
|
||||||
|
ScSceneUpdateLevelScriptProperty = 49,
|
||||||
|
ScSceneResetEntity = 50,
|
||||||
|
ScSceneLevelScriptResetBegin = 51,
|
||||||
|
ScSceneLevelScriptResetEnd = 52,
|
||||||
|
ScSceneSetBattle = 53,
|
||||||
|
ScSceneLevelScriptEventTrigger = 55,
|
||||||
|
ScSceneInteractiveEventTrigger = 56,
|
||||||
|
ScSceneTriggerClientLevelScriptEvent = 57,
|
||||||
|
ScSceneTriggerClientInteractiveEvent = 58,
|
||||||
|
ScSceneCrossSceneStatus = 59,
|
||||||
|
ScSceneDropCreate = 800,
|
||||||
|
ScSceneDropDelete = 801,
|
||||||
|
ScSceneDropModify = 802,
|
||||||
|
ScSceneGradeChangeNotify = 803,
|
||||||
|
ScSeamlessSceneDestroyNotify = 804,
|
||||||
|
ScSceneMonsterSpawnerStart = 805,
|
||||||
|
ScSceneMonsterSpawnerStop = 806,
|
||||||
|
ScSceneMonsterSpawnerComplete = 807,
|
||||||
|
ScSceneMonsterSpawnerBeginWave = 808,
|
||||||
|
ScSceneMonsterSpawnerWaveComplete = 809,
|
||||||
|
ScSceneMonsterSpawnerObjectDataBegin = 811,
|
||||||
|
ScSceneMonsterSpawnerObjectDataEnd = 812,
|
||||||
|
ScSceneLevelScriptTaskStateUpdate = 813,
|
||||||
|
ScSceneClientIdInfo = 814,
|
||||||
|
ScSceneLevelScriptTaskProgressUpdate = 815,
|
||||||
|
ScSceneLevelScriptTaskStartFinish = 816,
|
||||||
|
ScSceneInteractSpInteractive = 817,
|
||||||
|
ScSceneUpdateInteractiveMeta = 818,
|
||||||
|
ScSceneGradeModify = 819,
|
||||||
|
ScSceneSetStorySafeZone = 820,
|
||||||
|
ScSceneRepatriate = 821,
|
||||||
|
ScSceneSubmitRecycle = 822,
|
||||||
|
ScSceneLevelScriptSetDone = 823,
|
||||||
|
ScSyncCharBagInfo = 60,//
|
||||||
|
ScCharBagAddChar = 61,
|
||||||
|
ScCharBagSetTeam = 62,
|
||||||
|
ScCharBagSetCurrTeamIndex = 63,
|
||||||
|
ScCharBagSetTeamName = 64,
|
||||||
|
ScCharBagSetTeamLeader = 65,
|
||||||
|
ScCharBagSetMaxTeamMemberCount = 66,
|
||||||
|
ScCharBagTeamLeaderNotMatchNtf = 67,
|
||||||
|
ScCharBagDelChar = 68,
|
||||||
|
ScCharBagAddCharWithConversionNotify = 69,
|
||||||
|
ScSyncWallet = 70,//
|
||||||
|
ScWalletSyncMoney = 71,
|
||||||
|
ScCharSkillInfos = 78,
|
||||||
|
ScCharPotentialUnlock = 79,
|
||||||
|
ScCharLevelUp = 80,
|
||||||
|
ScCharSyncLevelExp = 82,
|
||||||
|
ScCharSetNormalSkill = 83,
|
||||||
|
ScCharSkillLevelUp = 84,
|
||||||
|
ScCharUnlockSkill = 85,
|
||||||
|
ScCharGainExpToast = 86,
|
||||||
|
ScCharSyncStatus = 87,
|
||||||
|
ScCharSetTeamSkill = 89,
|
||||||
|
ScEquipPuton = 90,
|
||||||
|
ScEquipPutoff = 91,
|
||||||
|
ScEquipMedicineModify = 92,
|
||||||
|
ScEquipRecycle = 93,
|
||||||
|
ScEquipEnhance = 94,
|
||||||
|
ScEquipProduce = 96,
|
||||||
|
ScSyncAllMission = 110,//
|
||||||
|
ScQuestStateUpdate = 111,
|
||||||
|
ScMissionStateUpdate = 112,
|
||||||
|
ScQuestFailed = 113,
|
||||||
|
ScMissionFailed = 114,
|
||||||
|
ScTrackMissionChange = 115,
|
||||||
|
ScQuestObjectivesUpdate = 116,
|
||||||
|
ScMissionDeleted = 117,
|
||||||
|
ScRollBlocMission = 120,
|
||||||
|
ScSyncBlocMissionInfo = 121,//
|
||||||
|
ScBlocCompletedMissionNumUpdate = 122,
|
||||||
|
ScQuestRollback = 123,
|
||||||
|
ScUpdateMissionProperty = 124,
|
||||||
|
ScSceneTriggerClientMissionEvent = 125,
|
||||||
|
ScMissionEventTrigger = 126,
|
||||||
|
ScDailyMissionInfoUpdate = 127,
|
||||||
|
ScSyncAllDialog = 130,//
|
||||||
|
ScFinishDialog = 131,
|
||||||
|
ScSyncAllGuide = 140,//
|
||||||
|
ScCompleteGuideGroupKeyStep = 141,
|
||||||
|
ScCompleteGuideGroup = 142,
|
||||||
|
ScAcceptGuideGroup = 143,
|
||||||
|
ScSyncAttr = 150,
|
||||||
|
ScSyncAllUnlock = 160,//
|
||||||
|
ScUnlockSystem = 161,
|
||||||
|
ScSyncAllBitset = 165,//
|
||||||
|
ScBitsetAdd = 166,
|
||||||
|
ScBitsetRemove = 167,
|
||||||
|
ScBitsetRemoveAll = 168,
|
||||||
|
ScFactorySync = 200,//
|
||||||
|
ScFactoryModifyFormulaMan = 201,
|
||||||
|
ScFactoryModifyStt = 202,
|
||||||
|
ScFactoryModifyVisibleFormula = 203,
|
||||||
|
ScFactoryModifyFormulaMode = 204,
|
||||||
|
ScFactorySyncOfflineInfo = 205,//
|
||||||
|
ScFactorySyncScope = 210,//
|
||||||
|
ScFactoryReleaseScope = 211,
|
||||||
|
ScFactoryModifyScope = 212,
|
||||||
|
ScFactoryModifyQuickbar = 213,
|
||||||
|
ScFactoryManuallyWorkExec = 214,
|
||||||
|
ScFactoryProductManualUnlock = 215,
|
||||||
|
ScFactoryModifySoil = 216,
|
||||||
|
ScFactorySoilReclaim = 217,
|
||||||
|
ScFactorySoilWater = 218,
|
||||||
|
ScFactorySoilCancel = 219,
|
||||||
|
ScFactorySoilHarvest = 220,
|
||||||
|
ScFactorySyncChapter = 221,//
|
||||||
|
ScFactoryModifyChapterNodes = 222,
|
||||||
|
ScFactoryModifyChapterComponents = 223,
|
||||||
|
ScFactoryModifyChapterScene = 224,
|
||||||
|
ScFactoryModifyChapterBlackboard = 225,
|
||||||
|
ScFactoryModifyChapterPinBoard = 226,
|
||||||
|
ScFactoryModifyChapterMap = 227,
|
||||||
|
ScFactoryHs = 231,
|
||||||
|
ScFactoryHsSync = 232,//
|
||||||
|
ScFactorySyncStatistic = 241,
|
||||||
|
ScFactoryModifyStatistic = 242,
|
||||||
|
ScFactoryStatisticRequire = 243,
|
||||||
|
ScFactoryHubWorkshopMake = 244,
|
||||||
|
ScFactoryHubTransportRouteModify = 245,
|
||||||
|
ScFactoryModifyStatisticBookmark = 246,
|
||||||
|
ScFactoryOpRet = 251,
|
||||||
|
ScFactoryObserverRet = 259,
|
||||||
|
ScWeaponPuton = 260,
|
||||||
|
ScWeaponBreakthrough = 262,
|
||||||
|
ScWeaponAddExp = 263,
|
||||||
|
ScWeaponAttachGem = 264,
|
||||||
|
ScWeaponDetachGem = 265,
|
||||||
|
ScWeaponRefineUpgrade = 266,
|
||||||
|
ScRewardToastBegin = 270,
|
||||||
|
ScRewardToastEnd = 271,
|
||||||
|
ScRewardDropMoneyToast = 272,
|
||||||
|
ScRewardToSceneBegin = 273,
|
||||||
|
ScRewardToSceneEnd = 274,
|
||||||
|
ScRewardDropSpItemToast = 275,
|
||||||
|
ScSyncAllBloc = 280,//
|
||||||
|
ScBlocSyncLevel = 281,
|
||||||
|
ScBlocTakeLevelReward = 282,
|
||||||
|
ScBlocShopBuy = 283,
|
||||||
|
ScDungeonBegin = 300,
|
||||||
|
ScEnterDungeon = 301,
|
||||||
|
ScRestartDungeon = 302,
|
||||||
|
ScLeaveDungeon = 303,
|
||||||
|
ScSyncStamina = 304,
|
||||||
|
ScSyncFullDungeonStatus = 306,
|
||||||
|
ScDungeonEnd = 359,
|
||||||
|
ScSyncAllMail = 400,//
|
||||||
|
ScGetMail = 401,
|
||||||
|
ScReadMail = 402,
|
||||||
|
ScGetMailAttachment = 403,
|
||||||
|
ScDelMailNotify = 404,
|
||||||
|
ScNewMailNotify = 405,
|
||||||
|
ScMarkStarMail = 406,
|
||||||
|
ScSyncGameMode = 430,
|
||||||
|
ScRemoveItemNewTags = 440,
|
||||||
|
ScSyncAllWiki = 470,
|
||||||
|
ScSyncAllStat = 500,
|
||||||
|
ScSyncStat = 501,
|
||||||
|
ScNewNoticeNotify = 600,
|
||||||
|
ScCreateOrder = 650,
|
||||||
|
ScOrderMsg = 651,
|
||||||
|
ScFriendBegin = 700,
|
||||||
|
ScFriendRequestSubmit = 701,
|
||||||
|
ScFriendRequestReject = 702,
|
||||||
|
ScFriendRequestAccept = 703,
|
||||||
|
ScFriendDelete = 704,
|
||||||
|
ScFriendSearchName = 705,
|
||||||
|
ScFriendRequestListSync = 706,
|
||||||
|
ScFriendListSync = 707,
|
||||||
|
ScFriendRequestAddNotify = 708,
|
||||||
|
ScFriendAddNotify = 709,
|
||||||
|
ScFriendEnd = 750,
|
||||||
|
ScUpdateGameVar = 901,
|
||||||
|
ScSyncAllGameVar = 902,//
|
||||||
|
ScUpdateMiniGame = 913,
|
||||||
|
ScSyncAllMiniGame = 914,//
|
||||||
|
ScCompleteMiniGame = 915,
|
||||||
|
ScRpgDungeonBegin = 950,
|
||||||
|
ScRpgDungeonBuy = 951,
|
||||||
|
ScRpgDungeonSell = 952,
|
||||||
|
ScRpgDungeonEquipPuton = 953,
|
||||||
|
ScRpgDungeonEquipPutoff = 954,
|
||||||
|
ScSyncRpgEquipColumn = 955,
|
||||||
|
ScSyncRpgDungeonBuffList = 956,
|
||||||
|
ScSyncRpgTeamLevel = 957,
|
||||||
|
ScSyncRpgLevelUp = 958,
|
||||||
|
ScRpgDungeonPickLvAbility = 959,
|
||||||
|
ScSyncRpgDungeonTimeInfo = 960,
|
||||||
|
ScSyncRpgDungeonAbility = 961,
|
||||||
|
ScRpgDungeonEnd = 999,
|
||||||
|
ScItemBagCommonSync = 1000,//
|
||||||
|
ScItemBagCommonModify = 1001,
|
||||||
|
ScItemBagScopeSync = 1002,//
|
||||||
|
ScItemBagScopeModify = 1003,
|
||||||
|
ScItemBagUseItem = 1004,
|
||||||
|
ScItemBagSetQuickBar = 1005,
|
||||||
|
ScItemBagSetQuickBarPos = 1006,
|
||||||
|
ScItemBagSetItemLock = 1007,
|
||||||
|
ScItemBagAbandonInBag = 1008,
|
||||||
|
ScItemBagBagToFactoryDepot = 1009,
|
||||||
|
ScItemBagTakeoutLostAndFound = 1031,
|
||||||
|
ScItemBagGotItemToast = 1032,
|
||||||
|
ScItemBagTrialCharDepotModify = 1033,
|
||||||
|
ScItemBagTrialCharDepotClear = 1034,
|
||||||
|
ScItemBagUseItemCase = 1035,
|
||||||
|
ScItemBagChgSpaceshipChapter = 1036,
|
||||||
|
ScItemBagEnd = 1049,
|
||||||
|
ScAddBuff = 1100,
|
||||||
|
ScRemoveBuff = 1101,
|
||||||
|
ScTriggerBuff = 1102,
|
||||||
|
ScClearBuffs = 1103,
|
||||||
|
ScCastSkill = 1160,
|
||||||
|
ScSyncHp = 1161,
|
||||||
|
ScSyncPoise = 1162,
|
||||||
|
ScSyncUltimateSpCellCnt = 1163,
|
||||||
|
ScSpawnEnemy = 1170,
|
||||||
|
ScSpawnSummon = 1171,
|
||||||
|
ScEntityPropertyChange = 1172,
|
||||||
|
ScBattleDebugInfo = 1173,
|
||||||
|
ScBattleGenerationChange = 1174,
|
||||||
|
ScAttachServerSkill = 1175,
|
||||||
|
ScDetachServerSkill = 1176,
|
||||||
|
ScAddServerBuff = 1177,
|
||||||
|
ScRemoveServerBuff = 1178,
|
||||||
|
ScSpaceshipSync = 1200,//
|
||||||
|
ScSpaceshipModifyRoom = 1201,
|
||||||
|
ScSpaceshipModifyChar = 1202,
|
||||||
|
ScSpaceshipPresentCharInfo = 1203,
|
||||||
|
ScSpaceshipCharFavorabilityChange = 1204,
|
||||||
|
ScSpaceshipRecvGiftFromChar = 1205,
|
||||||
|
ScSpaceshipPresentGiftToChar = 1206,
|
||||||
|
ScSpaceshipSyncRoomLevelUp = 1207,
|
||||||
|
ScSpaceshipSyncCharSkill = 1208,
|
||||||
|
ScSpaceshipSyncRoomStation = 1209,
|
||||||
|
ScSpaceshipManufacturingStationSync = 1210,
|
||||||
|
ScSpaceshipManufacturingStationStart = 1211,
|
||||||
|
ScSpaceshipManufacturingStationCancel = 1212,
|
||||||
|
ScSpaceshipManufacturingStationCollect = 1213,
|
||||||
|
ScSpaceshipModifyGrowCabin = 1214,
|
||||||
|
ScSpaceshipGrowCabinBreed = 1215,
|
||||||
|
ScSpaceshipGrowCabinSow = 1216,
|
||||||
|
ScSpaceshipGrowCabinHarvest = 1217,
|
||||||
|
ScSpaceshipGrowCabinCancel = 1218,
|
||||||
|
ScSpaceshipReportCharWorkModify = 1219,
|
||||||
|
ScSpaceshipReportOutputModify = 1220,
|
||||||
|
ScGameMechanicsBegin = 1250,
|
||||||
|
ScGameMechanicsSync = 1251,//
|
||||||
|
ScGameMechanicsSyncUnlockCondition = 1252,
|
||||||
|
ScGameMechanicsModifyRecords = 1253,
|
||||||
|
ScGameMechanicsSyncChallengeStart = 1254,
|
||||||
|
ScGameMechanicsSyncChallengeComplete = 1255,
|
||||||
|
ScGameMechanicsSyncCompletionReward = 1256,
|
||||||
|
ScGameMechanicsSyncEnterGameInst = 1257,
|
||||||
|
ScGameMechanicsSyncLeaveGameInst = 1258,
|
||||||
|
ScGameMechanicsSyncRestartGameInst = 1259,
|
||||||
|
ScGameMechanicsModifyInstTimeFreeze = 1260,
|
||||||
|
ScGameMechanicsEnd = 1299,
|
||||||
|
ScSnsBegin = 1300,
|
||||||
|
ScSnsGetMomentList = 1301,
|
||||||
|
ScSnsGetChatList = 1302,
|
||||||
|
ScSyncSnsAddDialog = 1303,
|
||||||
|
ScSnsMomentOption = 1304,
|
||||||
|
ScSyncSnsDialogModify = 1305,
|
||||||
|
ScSyncSnsAddMoment = 1306,
|
||||||
|
ScSnsMomentRead = 1307,
|
||||||
|
ScSnsReadDialog = 1308,
|
||||||
|
ScSyncSnsChatModify = 1309,
|
||||||
|
ScSnsEnd = 1330,
|
||||||
|
ScSettlementBegin = 1331,
|
||||||
|
ScSettlementSyncAll = 1332,//
|
||||||
|
ScSettlementSyncModify = 1333,
|
||||||
|
ScSettlementFinishRequires = 1334,
|
||||||
|
ScSettlementSetOfficer = 1335,
|
||||||
|
ScSettlementSelectRequire = 1336,
|
||||||
|
ScSettlementSetSubmitMode = 1337,
|
||||||
|
ScSettlementEnd = 1350,
|
||||||
|
ScShopBegin = 1351,
|
||||||
|
ScShopSync = 1352,//
|
||||||
|
ScShopSyncShopGroupCondition = 1353,
|
||||||
|
ScShopModifyShop = 1354,
|
||||||
|
ScShopSyncShopCondition = 1355,
|
||||||
|
ScShopSyncGoodsCondition = 1356,
|
||||||
|
ScShopModifyFrequencyLimit = 1357,
|
||||||
|
ScShopDeleteFrequencyLimit = 1358,
|
||||||
|
ScShopBuyResp = 1359,
|
||||||
|
ScShopSwapMoney = 1360,
|
||||||
|
ScShopEnd = 1370,
|
||||||
|
ScTdBegin = 1371,
|
||||||
|
ScTdGetTdList = 1372,
|
||||||
|
ScTdStart = 1373,
|
||||||
|
ScTdLeave = 1374,
|
||||||
|
ScSyncTdSettlement = 1375,
|
||||||
|
ScSyncTdFullStatus = 1376,
|
||||||
|
ScSyncTdDropItem = 1378,
|
||||||
|
ScTdPickDropItem = 1379,
|
||||||
|
ScTdBuyBuilding = 1380,
|
||||||
|
ScTdEnd = 1400,
|
||||||
|
ScAdventureBegin = 1401,
|
||||||
|
ScAdventureLevelModify = 1402,
|
||||||
|
ScAdventureSyncAll = 1403,//
|
||||||
|
ScAdventureEnd = 1430,
|
||||||
|
ScGemRecast = 1431,
|
||||||
|
ScGemEnd = 1440,
|
||||||
|
ScResetDailyAdventureTask = 1441,
|
||||||
|
ScDailyActivationModify = 1443,
|
||||||
|
ScAdventureTaskModify = 1444,
|
||||||
|
ScAdventureBookSync = 1445,//
|
||||||
|
ScAdventureBookStageModify = 1447,
|
||||||
|
ScTalentBegin = 1490,
|
||||||
|
ScCharUnlockTalentNode = 1491,
|
||||||
|
ScTalentEnd = 1529,
|
||||||
|
ScRacingDungeonBegin = 1530,
|
||||||
|
ScSyncRacingDungeonPassedLevel = 1531,
|
||||||
|
ScRacingDungeonEnter = 1532,
|
||||||
|
ScSyncRacingDungeonSettlement = 1533,
|
||||||
|
ScSyncRacingDungeonReconnect = 1534,
|
||||||
|
ScRacingDungeonBattlePassReceiveReward = 1535,
|
||||||
|
ScRacingDungeonGetBattlePass = 1536,
|
||||||
|
ScRacingDungeonGetAchievement = 1537,
|
||||||
|
ScRacingDungeonAchievementReceiveReward = 1538,
|
||||||
|
ScSyncRacingDungeonBuffModify = 1539,
|
||||||
|
ScSyncRacingDungeonAchievementModify = 1540,
|
||||||
|
ScSyncRacingTimerPause = 1541,
|
||||||
|
ScSyncRacingDungeonCompleteRoom = 1542,
|
||||||
|
ScSyncRacingDungeonCountdownEvent = 1543,
|
||||||
|
ScRacingDungeonEnd = 1600,
|
||||||
|
ScCharBagSetTempTeam = 1601,
|
||||||
|
ScCharBagRemoveTrialCharacter = 1602,
|
||||||
|
ScTrialCharacterEquipMedicineModify = 1603,
|
||||||
|
ScGachaBegin = 1610,
|
||||||
|
ScGachaSync = 1611,//
|
||||||
|
ScGachaModifyPoolInfo = 1612,
|
||||||
|
ScGachaSyncPullResult = 1613,
|
||||||
|
ScGachaModifyPoolRoleData = 1614,
|
||||||
|
ScGachaEnd = 1640,
|
||||||
|
ScGameTimeFreezeBegin = 1641,
|
||||||
|
ScGameTimeFreezeStartRsp = 1642,
|
||||||
|
ScGameTimeFreezeEndRsp = 1643,
|
||||||
|
ScGameTimeFreezeEnd = 1650,
|
||||||
|
ScActivityBegin = 1651,
|
||||||
|
ScActivitySync = 1652,//
|
||||||
|
ScActivityModify = 1653,
|
||||||
|
ScDailyCheckin = 1661,
|
||||||
|
ScActivityEnd = 1690,
|
||||||
|
ScMessageEnd = 4095,
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
53
Campofinale.sln
Normal file
53
Campofinale.sln
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.9.34902.65
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Campofinale", "Campofinale\Campofinale.csproj", "{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0} = {96C85239-92E8-4D22-B6BD-DD997C36C3E0}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Campofinale.Protocol", "Campofinale.Protocol\Campofinale.Protocol.csproj", "{96C85239-92E8-4D22-B6BD-DD997C36C3E0}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|ARM32 = Debug|ARM32
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|ARM32 = Release|ARM32
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|ARM32.ActiveCfg = Debug|ARM32
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|ARM32.Build.0 = Debug|ARM32
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|ARM32.ActiveCfg = Release|ARM32
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|ARM32.Build.0 = Release|ARM32
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{7338AADD-EFA7-407A-B2BE-AAE1560E2E8A}.Release|x86.Build.0 = Release|x86
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|ARM32.ActiveCfg = Debug|ARM32
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|ARM32.Build.0 = Debug|ARM32
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|ARM32.ActiveCfg = Release|ARM32
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|ARM32.Build.0 = Release|ARM32
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{96C85239-92E8-4D22-B6BD-DD997C36C3E0}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {63C48BE1-779C-4539-ADBF-5E4C44354730}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
2445
Campofinale/44_ScSyncAllMission.json
Normal file
2445
Campofinale/44_ScSyncAllMission.json
Normal file
File diff suppressed because it is too large
Load Diff
424
Campofinale/53_ScFactorySync.json
Normal file
424
Campofinale/53_ScFactorySync.json
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
{
|
||||||
|
"FormulaMan": {
|
||||||
|
"Unlocked": [
|
||||||
|
"component_mc_1",
|
||||||
|
"power_station_1",
|
||||||
|
"seedcollector_1",
|
||||||
|
"filling_powder_mc_1",
|
||||||
|
"handwork_anglem_flower2_1",
|
||||||
|
"handwork_plant_moss_powder_1",
|
||||||
|
"handwork_plant_moss_spc_powder_2",
|
||||||
|
"planter_1",
|
||||||
|
"handwork_bottled_rec_hp_2",
|
||||||
|
"furnance_1",
|
||||||
|
"handwork_corp2_flower2_1",
|
||||||
|
"handwork_bottled_food_1",
|
||||||
|
"tools_assebling_mc_1",
|
||||||
|
"handwork_bottled_insec1_1",
|
||||||
|
"handwork_plant_moss_powder_2",
|
||||||
|
"battle_frost_1",
|
||||||
|
"handwork_ebs_flower1_1",
|
||||||
|
"handwork_bottled_flower2spc_1",
|
||||||
|
"handwork_bottled_rec_hp_1",
|
||||||
|
"handwork_angles_flower2_1",
|
||||||
|
"miner_1",
|
||||||
|
"handwork_bottled_flower1spc_1",
|
||||||
|
"handwork_plant_moss_spc_powder_1",
|
||||||
|
"battle_cannon_1",
|
||||||
|
"handwork_port_soil_bbflower_1",
|
||||||
|
"winder_1",
|
||||||
|
"unloader_1",
|
||||||
|
"handwork_bottled_flower1spc_2",
|
||||||
|
"miner_3",
|
||||||
|
"shaper_1",
|
||||||
|
"handwork_port_soil_moss_1",
|
||||||
|
"handwork_ebm_flower1_1",
|
||||||
|
"battle_medic_1",
|
||||||
|
"travel_pole_1",
|
||||||
|
"miner_2",
|
||||||
|
"handwork_port_soil_sp_1",
|
||||||
|
"storager_1",
|
||||||
|
"handwork_bottled_insec2_1",
|
||||||
|
"battle_laser_1",
|
||||||
|
"power_diffuser_1",
|
||||||
|
"power_pole_2",
|
||||||
|
"handwork_corp1_flower1_1",
|
||||||
|
"thickener_1",
|
||||||
|
"travel_pole_2",
|
||||||
|
"handwork_animal_angles_1",
|
||||||
|
"loader_1",
|
||||||
|
"grinder_1",
|
||||||
|
"handwork_port_soil_moss_2",
|
||||||
|
"battle_turret_1",
|
||||||
|
"handwork_port_soil_sp_2"
|
||||||
|
],
|
||||||
|
"Visible": [
|
||||||
|
"handwork_plant_moss_powder_1",
|
||||||
|
"winder_equip_script_1",
|
||||||
|
"handwork_bottled_flower2spc_1",
|
||||||
|
"loader_1",
|
||||||
|
"planter_plant_moss_1_1",
|
||||||
|
"grinder_plant_moss_powder_2_1",
|
||||||
|
"winder_1",
|
||||||
|
"thickener_plant_moss_enr_powder_2_1",
|
||||||
|
"planter_plant_bbflower_1",
|
||||||
|
"winder_equip_script_3",
|
||||||
|
"tools_proc_bomb_1_1",
|
||||||
|
"shaper_1",
|
||||||
|
"grinder_plant_moss_powder_1_1",
|
||||||
|
"filling_bottled_rec_hp_3_1",
|
||||||
|
"travel_pole_1",
|
||||||
|
"grinder_plant_bbflower_powder_1_1",
|
||||||
|
"tools_proc_battery_2_1",
|
||||||
|
"tools_proc_battery_3_1",
|
||||||
|
"handwork_bottled_insec2_1",
|
||||||
|
"handwork_angles_flower2_1",
|
||||||
|
"handwork_bottled_insec1_1",
|
||||||
|
"handwork_port_soil_bbflower_1",
|
||||||
|
"component_glass_cmpt_1",
|
||||||
|
"thickener_originium_enr_powder_1",
|
||||||
|
"component_mc_1",
|
||||||
|
"grinder_crystal_powder_1",
|
||||||
|
"handwork_bottled_flower1spc_1",
|
||||||
|
"handwork_plant_moss_powder_2",
|
||||||
|
"grinder_quartz_powder_1",
|
||||||
|
"furnance_crystal_enr_powder_1",
|
||||||
|
"component_glass_enr_cmpt_1",
|
||||||
|
"handwork_ebs_flower1_1",
|
||||||
|
"battle_frost_1",
|
||||||
|
"thickener_iron_enr_powder_1",
|
||||||
|
"handwork_plant_moss_spc_powder_1",
|
||||||
|
"planter_plant_moss_2_1",
|
||||||
|
"furnance_carbon_enr_1",
|
||||||
|
"furnance_quartz_enr_1",
|
||||||
|
"filling_bottled_food_3_1",
|
||||||
|
"furnance_iron_nugget_1",
|
||||||
|
"battle_cannon_1",
|
||||||
|
"handwork_port_soil_sp_2",
|
||||||
|
"shaper_glass_bottle_1",
|
||||||
|
"battle_laser_1",
|
||||||
|
"handwork_bottled_rec_hp_1",
|
||||||
|
"filling_powder_mc_1",
|
||||||
|
"handwork_bottled_rec_hp_2",
|
||||||
|
"handwork_port_soil_sp_1",
|
||||||
|
"handwork_bottled_flower1spc_2",
|
||||||
|
"thickener_plant_moss_enr_powder_1_1",
|
||||||
|
"seedcollector_plant_sp_2",
|
||||||
|
"power_station_1",
|
||||||
|
"filling_bottled_rec_hp_2_1",
|
||||||
|
"component_iron_enr_cmpt_1",
|
||||||
|
"furnance_carbon_material_1",
|
||||||
|
"furnance_iron_enr_1",
|
||||||
|
"grinder_originium_powder_1",
|
||||||
|
"thickener_carbon_enr_powder_1",
|
||||||
|
"filling_bottled_rec_hp_1_1",
|
||||||
|
"battle_medic_1",
|
||||||
|
"shaper_iron_enr_bottle_1",
|
||||||
|
"tools_proc_battery_1_1",
|
||||||
|
"seedcollector_1",
|
||||||
|
"handwork_bottled_food_1",
|
||||||
|
"grinder_iron_powder_1",
|
||||||
|
"thickener_1",
|
||||||
|
"thickener_quartz_enr_powder_1",
|
||||||
|
"handwork_corp1_flower1_1",
|
||||||
|
"handwork_port_soil_moss_1",
|
||||||
|
"travel_pole_2",
|
||||||
|
"battle_turret_1",
|
||||||
|
"miner_3",
|
||||||
|
"furnance_crystal_enr_1",
|
||||||
|
"handwork_corp2_flower2_1",
|
||||||
|
"grinder_carbon_powder_1",
|
||||||
|
"seedcollector_plant_bbflower_1",
|
||||||
|
"handwork_ebm_flower1_1",
|
||||||
|
"tools_assebling_mc_1",
|
||||||
|
"unloader_1",
|
||||||
|
"filling_bottled_food_2_1",
|
||||||
|
"storager_1",
|
||||||
|
"shaper_iron_bottle_1",
|
||||||
|
"miner_2",
|
||||||
|
"furnance_quartz_glass_1",
|
||||||
|
"handwork_anglem_flower2_1",
|
||||||
|
"handwork_port_soil_moss_2",
|
||||||
|
"planter_1",
|
||||||
|
"seedcollector_plant_sp_1",
|
||||||
|
"furnance_crystal_shell_1",
|
||||||
|
"handwork_animal_angles_1",
|
||||||
|
"handwork_plant_moss_spc_powder_2",
|
||||||
|
"shaper_glass_enr_bottle_1",
|
||||||
|
"furnance_carbon_powder_1",
|
||||||
|
"thickener_crystal_enr_powder_1",
|
||||||
|
"seedcollector_plant_moss_1_1",
|
||||||
|
"component_iron_cmpt_1",
|
||||||
|
"seedcollector_plant_moss_2_1",
|
||||||
|
"winder_equip_script_2",
|
||||||
|
"filling_bottled_food_1_1"
|
||||||
|
],
|
||||||
|
"Modes": {
|
||||||
|
"Liquid": {
|
||||||
|
"BuildingIds": [
|
||||||
|
"pump_1",
|
||||||
|
"liquid_storager_nop_1",
|
||||||
|
"liquid_cleaner_1",
|
||||||
|
"miner_4",
|
||||||
|
"squirter_1",
|
||||||
|
"liquid_storager_1",
|
||||||
|
"squirter_nop_1",
|
||||||
|
"mix_pool_1",
|
||||||
|
"v_fluid_container_1",
|
||||||
|
"dumper_nop_1",
|
||||||
|
"dumper_1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"LevelUp": [
|
||||||
|
"item_animal_angles_1"
|
||||||
|
],
|
||||||
|
"ProductManual": [
|
||||||
|
"hdwk_item_plant_moss_spc_1_10",
|
||||||
|
"hdwk_item_drop_eb_m_1_1",
|
||||||
|
"hdwk_item_plant_bbflower_1_1",
|
||||||
|
"hdwk_item_drop_angle_m_1_1",
|
||||||
|
"hdwk_item_plant_tundra_insect_1_1",
|
||||||
|
"hdwk_item_plant_tundra_insect_2_10",
|
||||||
|
"hdwk_item_drop_animal_1_30",
|
||||||
|
"hdwk_item_drop_angle_s_1_1",
|
||||||
|
"hdwk_item_plant_moss_1_150",
|
||||||
|
"hdwk_item_plant_moss_2_1",
|
||||||
|
"hdwk_item_plant_tundra_insect_2_1",
|
||||||
|
"hdwk_item_plant_moss_spc_1_1",
|
||||||
|
"hdwk_item_plant_moss_2_50",
|
||||||
|
"hdwk_item_drop_eb_s_1_30",
|
||||||
|
"hdwk_item_plant_moss_spc_1_30",
|
||||||
|
"hdwk_item_plant_moss_1_1",
|
||||||
|
"hdwk_item_plant_tundra_insect_1_20",
|
||||||
|
"hdwk_item_drop_eb_s_1_1",
|
||||||
|
"hdwk_item_drop_animal_1_1",
|
||||||
|
"hdwk_item_plant_moss_1_15",
|
||||||
|
"hdwk_item_plant_sp_2_1",
|
||||||
|
"hdwk_item_plant_moss_2_30",
|
||||||
|
"hdwk_item_plant_moss_spc_2_10",
|
||||||
|
"hdwk_item_plant_sp_1_1",
|
||||||
|
"hdwk_item_plant_moss_spc_2_1",
|
||||||
|
"hdwk_item_drop_animal_1_10",
|
||||||
|
"hdwk_item_plant_moss_1_100",
|
||||||
|
"hdwk_item_drop_eb_s_1_10",
|
||||||
|
"hdwk_item_drop_angle_s_1_10"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Stt": {
|
||||||
|
"Nodes": [
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_dumper_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_filling_mode_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_liquid_storager_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_mix_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_pipe_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_planter_mode_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_pump_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_1_splitter_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_connector_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_converger_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_furnance_mode_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_liquid_cleaner_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_miner_4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_mix_1_unlock_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_shaper_mode_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_jinlong_2_squirter_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_battle_medic_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_battle_turret_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_cmpt_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_diffuser_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_furnance_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_grinder_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_miner_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_pole_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_shaper_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_storager_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_1_winder_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_asm_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_battle_cannon_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_battle_frost_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_battle_laser_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_belt_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_connector_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_field_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_filling_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_miner_2",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_plant_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_power_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_splitter_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_2_travel_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_cannon_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_laser_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_lightning_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_shockwave_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_sniper_1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_battle_turret_2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_converger_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_field_2",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_miner_3",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_thickener_1",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_tundra_3_travel_2",
|
||||||
|
"State": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Packages": [
|
||||||
|
{
|
||||||
|
"Id": "tech_group_jinlong",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_group_tundra",
|
||||||
|
"State": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Layers": [
|
||||||
|
{
|
||||||
|
"Id": "tech_group_jinlong_liquid",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_group_tundra_iron",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_group_tundra_originium",
|
||||||
|
"State": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Id": "tech_group_tundra_quartz",
|
||||||
|
"State": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
440
Campofinale/92_ScSyncAllBitset.json
Normal file
440
Campofinale/92_ScSyncAllBitset.json
Normal file
@ -0,0 +1,440 @@
|
|||||||
|
{
|
||||||
|
"Bitset": [
|
||||||
|
{
|
||||||
|
"Type": 7,
|
||||||
|
"Value": [
|
||||||
|
"2",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"11529215046068469760",
|
||||||
|
"262164",
|
||||||
|
"0",
|
||||||
|
"4611686018494496768",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8589934592",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"144115188075855872",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8388608",
|
||||||
|
"4611686018439970816",
|
||||||
|
"324259173170718981",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"126",
|
||||||
|
"0",
|
||||||
|
"268435456",
|
||||||
|
"288230376151711744",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"1593149468230811650",
|
||||||
|
"100292",
|
||||||
|
"17592186044416"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 3,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 45,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 13,
|
||||||
|
"Value": [
|
||||||
|
"51810140172"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 22,
|
||||||
|
"Value": [
|
||||||
|
"637536256"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 30,
|
||||||
|
"Value": [
|
||||||
|
"670695769600703488",
|
||||||
|
"7849126204"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 9,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 23,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"122357090304"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 46,
|
||||||
|
"Value": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 44,
|
||||||
|
"Value": [
|
||||||
|
"9745508118585934080",
|
||||||
|
"2531075783884815"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 19
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 14,
|
||||||
|
"Value": [
|
||||||
|
"9223372036855169152",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"2752512",
|
||||||
|
"0",
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 47,
|
||||||
|
"Value": [
|
||||||
|
"3196644842209280"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 10,
|
||||||
|
"Value": [
|
||||||
|
"140737488355328",
|
||||||
|
"1335555265063288832",
|
||||||
|
"12124253146834798728",
|
||||||
|
"16619141365993580464",
|
||||||
|
"12333486116532429"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 39,
|
||||||
|
"Value": [
|
||||||
|
"503839996",
|
||||||
|
"0",
|
||||||
|
"17042430230528",
|
||||||
|
"17180393728"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 1,
|
||||||
|
"Value": [
|
||||||
|
"2305845352252574734",
|
||||||
|
"11276608979599364",
|
||||||
|
"1193501217834139760",
|
||||||
|
"17582059550928803968",
|
||||||
|
"234189274820750654",
|
||||||
|
"0",
|
||||||
|
"6917529027708190720",
|
||||||
|
"549755813888",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8589934592",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"7351915285449801728",
|
||||||
|
"1610619010",
|
||||||
|
"0",
|
||||||
|
"57174604644352",
|
||||||
|
"0",
|
||||||
|
"576460752303423488",
|
||||||
|
"9241324862841349840",
|
||||||
|
"13835058059188931635",
|
||||||
|
"9195049235800194943",
|
||||||
|
"8755314334957043712",
|
||||||
|
"1261617",
|
||||||
|
"0",
|
||||||
|
"5373428292625891710",
|
||||||
|
"5835082701971406914",
|
||||||
|
"6674057571101343842",
|
||||||
|
"432345564325506799",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"11392984662570696706",
|
||||||
|
"2348486468193847252",
|
||||||
|
"19791209336838"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 42,
|
||||||
|
"Value": [
|
||||||
|
"144405463440556032",
|
||||||
|
"17592186044928",
|
||||||
|
"2305847510373122048",
|
||||||
|
"9261652635834909185",
|
||||||
|
"1225119838280618056",
|
||||||
|
"2291382234121218",
|
||||||
|
"8320"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 50,
|
||||||
|
"Value": [
|
||||||
|
"51541704716",
|
||||||
|
"17179869184"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 32,
|
||||||
|
"Value": [
|
||||||
|
"8796093022208",
|
||||||
|
"67108864",
|
||||||
|
"8192",
|
||||||
|
"40532396646334464",
|
||||||
|
"216188176225009664",
|
||||||
|
"7585212069490720768",
|
||||||
|
"68719477760",
|
||||||
|
"1204716198856941568",
|
||||||
|
"35786910376027",
|
||||||
|
"1",
|
||||||
|
"6878201854087904",
|
||||||
|
"201535533972553728",
|
||||||
|
"562949953422484"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 49,
|
||||||
|
"Value": [
|
||||||
|
"1081145935319335202",
|
||||||
|
"2267743516716"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 11,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"458480242655232"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 12,
|
||||||
|
"Value": [
|
||||||
|
"51810140172",
|
||||||
|
"531424821771251712",
|
||||||
|
"590604267522",
|
||||||
|
"262144"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 31,
|
||||||
|
"Value": [
|
||||||
|
"18446673704948596736",
|
||||||
|
"10351514792732131327",
|
||||||
|
"3038669698868181091",
|
||||||
|
"14676867182063746867",
|
||||||
|
"2259954429851840863",
|
||||||
|
"14082403297860126378",
|
||||||
|
"452585"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 8,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"700314552419483648",
|
||||||
|
"6883146427956985856",
|
||||||
|
"10678850801135",
|
||||||
|
"12557541982456905728"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 26,
|
||||||
|
"Value": [
|
||||||
|
"1125899906842620"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 21,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"17572948988976431104",
|
||||||
|
"13107933272249661048",
|
||||||
|
"13808029682097634519",
|
||||||
|
"175"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 15,
|
||||||
|
"Value": [
|
||||||
|
"0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 18,
|
||||||
|
"Value": [
|
||||||
|
"0",
|
||||||
|
"2200096998416",
|
||||||
|
"18375812389242293472",
|
||||||
|
"1424917274804735",
|
||||||
|
"270397203"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 2,
|
||||||
|
"Value": [
|
||||||
|
"90170430014915120",
|
||||||
|
"11583546498734869004",
|
||||||
|
"3910405411899142210",
|
||||||
|
"1097",
|
||||||
|
"5622463761458790540",
|
||||||
|
"6448939136",
|
||||||
|
"18302628885633695744",
|
||||||
|
"1941299076985287561",
|
||||||
|
"4165321356736086175",
|
||||||
|
"734655911615783166",
|
||||||
|
"7816980527214433829",
|
||||||
|
"18435361420267951154",
|
||||||
|
"5476799465637475382",
|
||||||
|
"2896736039472204290",
|
||||||
|
"18139821896924482577",
|
||||||
|
"16545632413779394543",
|
||||||
|
"17543135999577665520",
|
||||||
|
"160002550206265"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 27,
|
||||||
|
"Value": [
|
||||||
|
"21536791257814024"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 16,
|
||||||
|
"Value": [
|
||||||
|
"18446744073709551615",
|
||||||
|
"18446744073709551615",
|
||||||
|
"18446744073709551615",
|
||||||
|
"18446744073709551615"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 17,
|
||||||
|
"Value": [
|
||||||
|
"16510976"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 38,
|
||||||
|
"Value": [
|
||||||
|
"34628173824"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 5,
|
||||||
|
"Value": [
|
||||||
|
"2305845352252573710",
|
||||||
|
"11276608979599364",
|
||||||
|
"1193501217834139728",
|
||||||
|
"12970373532501415936",
|
||||||
|
"1660298764574",
|
||||||
|
"0",
|
||||||
|
"6917529027708190720",
|
||||||
|
"549755813888",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"8589934592",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"7351915285449801728",
|
||||||
|
"1610619010",
|
||||||
|
"0",
|
||||||
|
"57174604644352",
|
||||||
|
"0",
|
||||||
|
"576460752303423488",
|
||||||
|
"9241324862841349840",
|
||||||
|
"13835058059187618867",
|
||||||
|
"9195048686043332479",
|
||||||
|
"576460752303423488",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"5373428292625891710",
|
||||||
|
"5835082701971406914",
|
||||||
|
"6674057571101343842",
|
||||||
|
"432345564325506799",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"11392984662570696706",
|
||||||
|
"2348486468193847252",
|
||||||
|
"19791209336838"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 41,
|
||||||
|
"Value": [
|
||||||
|
"668232592512256000",
|
||||||
|
"2424840448"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 48,
|
||||||
|
"Value": [
|
||||||
|
"5290262761236124",
|
||||||
|
"18014462933991424"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 43,
|
||||||
|
"Value": [
|
||||||
|
"137438953472",
|
||||||
|
"4",
|
||||||
|
"0",
|
||||||
|
"0",
|
||||||
|
"32768"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Type": 35
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
368
Campofinale/93_ScSceneMapMarkSync.json
Normal file
368
Campofinale/93_ScSceneMapMarkSync.json
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
{
|
||||||
|
"SceneStaticMapMarkList": [
|
||||||
|
{
|
||||||
|
"Index": 251
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 460
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 601
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 256
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 459
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 283
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 326
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 324
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 350
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 255
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 426
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 441
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 345
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 333
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 306
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 215
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 264
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 250
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 457
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 268
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 605
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 439
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 261
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 246
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 455
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 320
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 238
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 435
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 338
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 349
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 421
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 218
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 325
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 437
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 318
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 265
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 263
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 327
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 213
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 419
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 526
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 431
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 305
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 440
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 343
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 422
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 254
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 344
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 236
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 539
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 347
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 276
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 237
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 260
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 436
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 456
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 337
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 252
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 220
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 515
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 425
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 303
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 536
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 239
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 214
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 316
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 428
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 266
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 277
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 323
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 430
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 442
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 235
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 594
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 595
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 462
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 219
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 434
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 322
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 282
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 346
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 308
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 212
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 420
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 310
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 281
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 329
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 342
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 336
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 418
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 249
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 469
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 321
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 309
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 438
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 278
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 423
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 472
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 253
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 427
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 248
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 330
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 351
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 247
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 468
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 223
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 245
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 307
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 224
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 269
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 416
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 470
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 311
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 267
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 319
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 524
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 217
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 304
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Index": 262
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TrackPoint": {}
|
||||||
|
}
|
81
Campofinale/Campofinale.csproj
Normal file
81
Campofinale/Campofinale.csproj
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<Platforms>AnyCPU;x86;ARM32</Platforms>
|
||||||
|
<StartupObject>Program</StartupObject>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Remove="Controllers\**" />
|
||||||
|
<Compile Remove="resources\binoutput\**" />
|
||||||
|
<EmbeddedResource Remove="Controllers\**" />
|
||||||
|
<EmbeddedResource Remove="resources\binoutput\**" />
|
||||||
|
<None Remove="Controllers\**" />
|
||||||
|
<None Remove="resources\binoutput\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CsvHelper" Version="33.0.1" />
|
||||||
|
<PackageReference Include="Google.Protobuf" Version="3.27.2" />
|
||||||
|
<PackageReference Include="HttpServerLite" Version="2.1.5" />
|
||||||
|
<PackageReference Include="MongoDB.Driver" Version="3.0.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="NLua" Version="1.7.3" />
|
||||||
|
<PackageReference Include="Pastel" Version="5.1.0" />
|
||||||
|
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
|
<PackageReference Include="SQLiteNetExtensions" Version="2.1.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Campofinale.Protocol\Campofinale.Protocol.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="44_ScSyncAllMission.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="53_ScFactorySync.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="92_ScSyncAllBitset.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="93_ScSceneMapMarkSync.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\GachaHistory\index_noplayerfound.html">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\Static\bar.jpg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\Static\bg.jpg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\Static\cs_bg.jpg">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\GachaHistory\index.html">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\Static\ja-jp.otf">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Data\PlayerConsole\index.html">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="ScFactorySyncChapter.json">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Data\PlayerConsole\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
54
Campofinale/Commands/BaseCommands.cs
Normal file
54
Campofinale/Commands/BaseCommands.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Game.Entities;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands
|
||||||
|
{
|
||||||
|
public static class BaseCommands
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
[Server.Command("scene", "Change scene",true)]
|
||||||
|
public static void SceneCmd(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 1) return;
|
||||||
|
int sceneNumId = int.Parse(args[0]);
|
||||||
|
target.EnterScene(sceneNumId);
|
||||||
|
CommandManager.SendMessage(sender, "Changing scene");
|
||||||
|
|
||||||
|
}
|
||||||
|
[Server.Command("target", "Set a target uid", false)]
|
||||||
|
public static void TargetCmd(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (sender != null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "This command can't be used ingame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender,"Use: /target (uid)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string id = args[0];
|
||||||
|
Player player = Server.clients.Find(c=>c.accountId == id);
|
||||||
|
if (player == null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Only online players can be set as target");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CommandManager.targetId = id;
|
||||||
|
CommandManager.SendMessage(sender, "Set Target player to " +id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
101
Campofinale/Commands/CommandManager.cs
Normal file
101
Campofinale/Commands/CommandManager.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
namespace Campofinale.Commands
|
||||||
|
{
|
||||||
|
using Pastel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Network;
|
||||||
|
|
||||||
|
public static class CommandManager
|
||||||
|
{
|
||||||
|
private static List<Type> s_handlerTypes = new List<Type>();
|
||||||
|
public static ImmutableDictionary<string, (Server.CommandAttribute, Server.CommandAttribute.HandlerDelegate)> s_notifyReqGroup;
|
||||||
|
public static string targetId;
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
var handlers = ImmutableDictionary.CreateBuilder<string, (Server.CommandAttribute, Server.CommandAttribute.HandlerDelegate)>();
|
||||||
|
|
||||||
|
foreach (var type in s_handlerTypes)
|
||||||
|
{
|
||||||
|
foreach (var method in type.GetMethods())
|
||||||
|
{
|
||||||
|
var attribute = method.GetCustomAttribute<Server.CommandAttribute> ();
|
||||||
|
if (attribute == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var parameterInfo = method.GetParameters();
|
||||||
|
var senderParameter = Expression.Parameter(typeof(Player));
|
||||||
|
var commandParameter = Expression.Parameter(typeof(string));
|
||||||
|
var argsParameter = Expression.Parameter(typeof(string[]));
|
||||||
|
var targetParameter = Expression.Parameter(typeof(Player));
|
||||||
|
|
||||||
|
var call = Expression.Call(method,
|
||||||
|
Expression.Convert(senderParameter, parameterInfo[0].ParameterType),
|
||||||
|
Expression.Convert(commandParameter, parameterInfo[1].ParameterType),
|
||||||
|
Expression.Convert(argsParameter, parameterInfo[2].ParameterType),
|
||||||
|
Expression.Convert(targetParameter, parameterInfo[3].ParameterType));
|
||||||
|
|
||||||
|
var lambda = Expression.Lambda<Server.CommandAttribute.HandlerDelegate>(call,senderParameter, commandParameter, argsParameter,targetParameter);
|
||||||
|
|
||||||
|
if (!handlers.TryGetKey(attribute.command, out _))
|
||||||
|
handlers.Add(attribute.command, (attribute, lambda.Compile()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s_notifyReqGroup = handlers.ToImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Notify(Player sender,string cmd, string[] args,Player target)
|
||||||
|
{
|
||||||
|
if (s_notifyReqGroup.TryGetValue(cmd, out var handler))
|
||||||
|
{
|
||||||
|
if (handler.Item1.requiredTarget)
|
||||||
|
{
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
handler.Item2.Invoke(sender,cmd, args, target);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessage(sender,"This command require a target player, set one with /target (uid)");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handler.Item2.Invoke(sender, cmd, args, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessage(sender, $"Command not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddReqGroupHandler(Type type)
|
||||||
|
{
|
||||||
|
s_handlerTypes.Add(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void SendMessage(Player sender, string msg)
|
||||||
|
{
|
||||||
|
if (sender == null)
|
||||||
|
{
|
||||||
|
Logger.Print(msg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//For sending to player command prompt page made by Xannix
|
||||||
|
sender.temporanyChatMessages.Add(msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
39
Campofinale/Commands/Handlers/CommandAccount.cs
Normal file
39
Campofinale/Commands/Handlers/CommandAccount.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandAccount
|
||||||
|
{
|
||||||
|
[Server.Command("account", "account command")]
|
||||||
|
public static void Handle(Player sender,string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (sender != null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "This command can't be used ingame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Usage: account create|reset (username)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "create":
|
||||||
|
DatabaseManager.db.CreateAccount(args[1]);
|
||||||
|
break;
|
||||||
|
case "reset":
|
||||||
|
CommandManager.SendMessage(sender, "Reset is not implemented yet");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CommandManager.SendMessage(sender, "Example: account create (username)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
Campofinale/Commands/Handlers/CommandAdd.cs
Normal file
88
Campofinale/Commands/Handlers/CommandAdd.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers;
|
||||||
|
|
||||||
|
public static class CommandAdd
|
||||||
|
{
|
||||||
|
[Server.Command("add", "Adds items, weapons or characters", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if(args.Length < 2)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /add (item|weapon|char) (item/weapon/char id) (amount/lvl)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string message = "";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "item":
|
||||||
|
Item item=target.inventoryManager.AddItem(args[1], int.Parse(args[2]));
|
||||||
|
message = $"Item {args[1]} was added to {target.nickname}";
|
||||||
|
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, item));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "weapon":
|
||||||
|
Item wep = target.inventoryManager.AddWeapon(args[1], Convert.ToUInt64(args[2]));
|
||||||
|
message = $"Weapon {args[1]} was added to {target.nickname}";
|
||||||
|
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, wep));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "char":
|
||||||
|
int lvl = int.Parse(args[2]);
|
||||||
|
|
||||||
|
if(lvl < 1 || lvl > 80)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Level can't be less than 1 or more than 80");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character character = new Character(target.roleId, args[1], lvl);
|
||||||
|
|
||||||
|
if(target.chars.Find(c => c.id == character.id) != null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Character already exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lvl <= 20) character.breakNode = "";
|
||||||
|
if(lvl > 20 && lvl <= 40) character.breakNode = "charBreak20";
|
||||||
|
if(lvl > 40 && lvl <= 60) character.breakNode = "charBreak40";
|
||||||
|
if(lvl > 60 && lvl <= 70) character.breakNode = "charBreak60";
|
||||||
|
if(lvl > 70) character.breakNode = "charBreak70";
|
||||||
|
|
||||||
|
target.chars.Add(character);
|
||||||
|
target.SaveCharacters();
|
||||||
|
|
||||||
|
message = $"Character {character.id} was added to {target.nickname}.";
|
||||||
|
CommandManager.SendMessage(sender, message);
|
||||||
|
target.Send(new PacketScCharBagAddChar(target, character));
|
||||||
|
Item weapon = target.inventoryManager.items.Find(i => i.guid == character.weaponGuid);
|
||||||
|
if(weapon!=null)target.Send(new PacketScItemBagScopeModify(target, weapon));
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CommandManager.SendMessage(sender, "Unknown argument, use item, weapon or character");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.inventoryManager.Save();
|
||||||
|
CommandManager.SendMessage(sender, $"{message}.");
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"An error occurred: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
Campofinale/Commands/Handlers/CommandCharInfo.cs
Normal file
59
Campofinale/Commands/Handlers/CommandCharInfo.cs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public class CommandCharInfo
|
||||||
|
{
|
||||||
|
[Server.Command("charinfo", "Information about characters", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
// maybe we could use localization here
|
||||||
|
// string lang = "EN";
|
||||||
|
// Dictionary<string, string> locTable = JsonConvert.DeserializeObject<Dictionary<string, string>>(ReadJsonFile($"TableCfg/I18nTextTable_{lang}.json"));
|
||||||
|
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /charinfo (id)");
|
||||||
|
CommandManager.SendMessage(sender, "\nAll characters:");
|
||||||
|
foreach (Character chara in target.chars)
|
||||||
|
{
|
||||||
|
//locTable.TryGetValue(characterTable.Values.ToList().Find(x => x.charId == chara.id).name.id, out string aName);
|
||||||
|
string aName = characterTable.Values.ToList().Find(x => x.charId == chara.id).engName;
|
||||||
|
CommandManager.SendMessage(sender, $"{aName} ({chara.id})");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//locTable.TryGetValue(characterTable.Values.ToList().Find(x => x.charId == args[0]).name.id, out string name);
|
||||||
|
string name = characterTable.Values.ToList().Find(x => x.charId == args[0]).engName;
|
||||||
|
|
||||||
|
Character character = target.GetCharacter(args[0]);
|
||||||
|
Item weapon = DatabaseManager.db.LoadInventoryItems(target.roleId).Find(w => w.guid == character.weaponGuid);
|
||||||
|
|
||||||
|
string responce = @$"
|
||||||
|
// {name} ({character.id})
|
||||||
|
│ guid: {character.guid}
|
||||||
|
│ level: {character.level}
|
||||||
|
│ curHp: {character.curHp}
|
||||||
|
│ potential: {character.potential}
|
||||||
|
│ breakNode: {character.breakNode}
|
||||||
|
│
|
||||||
|
├ // Weapon ({weapon.id})
|
||||||
|
│ guid: {character.weaponGuid}
|
||||||
|
│ level: {weapon.level}
|
||||||
|
│ weapon breakThroughLvl: {weapon.breakthroughLv}
|
||||||
|
└ weapon potential: {weapon.refineLv}";
|
||||||
|
CommandManager.SendMessage(sender, responce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
Campofinale/Commands/Handlers/CommandClear.cs
Normal file
23
Campofinale/Commands/Handlers/CommandClear.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandClear
|
||||||
|
{
|
||||||
|
[Server.Command("clear", "clears the console", false)]
|
||||||
|
public static void Handle(Player sender,string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (sender != null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "This command can't be used ingame");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Console.Clear();
|
||||||
|
Logger.Print("Console cleared");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
43
Campofinale/Commands/Handlers/CommandHeal.cs
Normal file
43
Campofinale/Commands/Handlers/CommandHeal.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using Campofinale.Game.Entities;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandHeal
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Command("heal", "Revives/Heals your team characters", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
target.GetCurTeam().ForEach(chara =>
|
||||||
|
{
|
||||||
|
chara.curHp = chara.CalcAttributes()[AttributeType.MaxHp].val;
|
||||||
|
ScCharSyncStatus state = new ScCharSyncStatus()
|
||||||
|
{
|
||||||
|
Objid=chara.guid,
|
||||||
|
IsDead=chara.curHp < 1,
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp=chara.curHp,
|
||||||
|
Ultimatesp=chara.ultimateSp
|
||||||
|
}
|
||||||
|
};
|
||||||
|
target.Send(ScMsgId.ScCharSyncStatus, state);
|
||||||
|
});
|
||||||
|
target.Send(ScMsgId.ScSceneRevival, new ScSceneRevival()
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
target.sceneManager.LoadCurrentTeamEntities();
|
||||||
|
target.Send(new PacketScSelfSceneInfo(target,SelfInfoReasonType.SlrReviveRest));
|
||||||
|
CommandManager.SendMessage(sender, "Healed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Campofinale/Commands/Handlers/CommandHelp.cs
Normal file
22
Campofinale/Commands/Handlers/CommandHelp.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandHelp
|
||||||
|
{
|
||||||
|
[Server.Command("help", "Show list of commands", false)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "List of possible commands: ");
|
||||||
|
foreach (var command in CommandManager.s_notifyReqGroup)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"/{command.Key} - {command.Value.Item1.desc} (Require Target: {command.Value.Item1.requiredTarget})");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
Campofinale/Commands/Handlers/CommandIdList.cs
Normal file
50
Campofinale/Commands/Handlers/CommandIdList.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public class CommandIdList
|
||||||
|
{
|
||||||
|
[Server.Command("idlist", "List of all ids", false)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /idlist (chars|enemies|scenes)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args[0])
|
||||||
|
{
|
||||||
|
case "chars":
|
||||||
|
CommandManager.SendMessage(sender, "Character ids:");
|
||||||
|
characterTable.Values.ToList().ForEach(c => {
|
||||||
|
CommandManager.SendMessage(sender, $"{c.charId} ({c.engName})");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "enemies":
|
||||||
|
CommandManager.SendMessage(sender, "Enemy ids:");
|
||||||
|
enemyTable.Values.ToList().ForEach(e => {
|
||||||
|
CommandManager.SendMessage(sender, $"{e.enemyId} (templateId: {e.templateId})");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "scenes":
|
||||||
|
CommandManager.SendMessage(sender, "Scene ids:");
|
||||||
|
levelDatas.ForEach(s => {
|
||||||
|
CommandManager.SendMessage(sender, $"{s.id} (id: {s.idNum})");
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
CommandManager.SendMessage(sender, "Category not found");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
Campofinale/Commands/Handlers/CommandKick.cs
Normal file
19
Campofinale/Commands/Handlers/CommandKick.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandKick
|
||||||
|
{
|
||||||
|
[Server.Command("kick", "kick target", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
target.Kick(CODE.ErrKickSessionEnd, "Kicked");
|
||||||
|
CommandManager.SendMessage(sender,"Kicked " + target.accountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
157
Campofinale/Commands/Handlers/CommandLevel.cs
Normal file
157
Campofinale/Commands/Handlers/CommandLevel.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using Campofinale.Commands;
|
||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Character
|
||||||
|
{
|
||||||
|
public static class CharacterManager
|
||||||
|
{
|
||||||
|
[Server.Command("level", "Update character/item level", true)]
|
||||||
|
public static void HandleLevel(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, @"Use:
|
||||||
|
/level (char_id/item_id) (level) - Update specific character/item level
|
||||||
|
/level (level) - Update all characters and items to level");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (args.Length == 1)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(args[0], out int level))
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Invalid level number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateAllLevels(sender, target, level);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string id = args[0];
|
||||||
|
if (!int.TryParse(args[1], out int level))
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Invalid level number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UpdateSingleLevel(sender, target, id, level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception err)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"An error occurred: {err}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateAllLevels(Player sender, Player target, int level)
|
||||||
|
{
|
||||||
|
level = Math.Max(1, Math.Min(level, 80));
|
||||||
|
|
||||||
|
int updatedCharCount = 0;
|
||||||
|
foreach (var item in ResourceManager.itemTable)
|
||||||
|
{
|
||||||
|
if (item.Key.StartsWith("chr_"))
|
||||||
|
{
|
||||||
|
AddOrUpdateCharacter(target, item.Key, level);
|
||||||
|
updatedCharCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int updatedItemCount = 0;
|
||||||
|
foreach (var item in target.inventoryManager.items)
|
||||||
|
{
|
||||||
|
if (item.id.StartsWith("wpn_"))
|
||||||
|
{
|
||||||
|
item.amount = 0;
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, item));
|
||||||
|
|
||||||
|
item.amount = 1;
|
||||||
|
item.level = (ulong)level;
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, item));
|
||||||
|
|
||||||
|
updatedItemCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.SaveCharacters();
|
||||||
|
target.inventoryManager.Save();
|
||||||
|
CommandManager.SendMessage(sender, $"Updated {updatedCharCount} characters and {updatedItemCount} weapons to level {level}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSingleLevel(Player sender, Player target, string id, int level)
|
||||||
|
{
|
||||||
|
level = Math.Max(1, Math.Min(level, 80));
|
||||||
|
|
||||||
|
if (id.StartsWith("chr_"))
|
||||||
|
{
|
||||||
|
if (!ResourceManager.itemTable.ContainsKey(id))
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"Invalid character ID: {id}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddOrUpdateCharacter(target, id, level);
|
||||||
|
target.SaveCharacters();
|
||||||
|
CommandManager.SendMessage(sender, $"Character {id} level updated to {level}");
|
||||||
|
}
|
||||||
|
else if (id.StartsWith("wpn_"))
|
||||||
|
{
|
||||||
|
var item = target.inventoryManager.GetItemById(id);
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"Item not found: {id}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
item.amount = 0;
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, item));
|
||||||
|
|
||||||
|
item.amount = 1;
|
||||||
|
item.level = (ulong)level;
|
||||||
|
target.Send(new PacketScItemBagScopeModify(target, item));
|
||||||
|
|
||||||
|
target.inventoryManager.Save();
|
||||||
|
CommandManager.SendMessage(sender, $"Weapon {id} level updated to {level}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, $"Invalid ID format: {id} (must start with 'chr_' or 'wpn_')");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Character AddOrUpdateCharacter(Player target, string charId, int level)
|
||||||
|
{
|
||||||
|
Character existingChar = target.chars.Find(c => c.id == charId);
|
||||||
|
if (existingChar != null)
|
||||||
|
{
|
||||||
|
existingChar.level = level;
|
||||||
|
existingChar.breakNode = GetBreakNodeByLevel(level);
|
||||||
|
|
||||||
|
target.Send(new PacketScCharBagDelChar(target, existingChar));
|
||||||
|
target.Send(new PacketScCharBagAddChar(target, existingChar));
|
||||||
|
|
||||||
|
return existingChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character character = new Character(target.roleId, charId, level);
|
||||||
|
character.breakNode = GetBreakNodeByLevel(level);
|
||||||
|
target.chars.Add(character);
|
||||||
|
|
||||||
|
target.Send(new PacketScCharBagAddChar(target, character));
|
||||||
|
|
||||||
|
return character;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetBreakNodeByLevel(int level)
|
||||||
|
{
|
||||||
|
if (level <= 20) return "";
|
||||||
|
if (level <= 40) return "charBreak20";
|
||||||
|
if (level <= 60) return "charBreak40";
|
||||||
|
if (level <= 70) return "charBreak60";
|
||||||
|
return "charBreak70";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
Campofinale/Commands/Handlers/CommandNickname.cs
Normal file
33
Campofinale/Commands/Handlers/CommandNickname.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
|
||||||
|
public static class CommandNickname
|
||||||
|
{
|
||||||
|
[Server.Command("nickname", "Changes nickname", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /nickname (your new nickname)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
args[i] = Uri.UnescapeDataString(args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
target.nickname = string.Join(" ", args);
|
||||||
|
target.Save();
|
||||||
|
target.Send(new PacketScSetName(target, target.nickname));
|
||||||
|
CommandManager.SendMessage(sender, $"Nickname was changed to {target.nickname}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Campofinale/Commands/Handlers/CommandPlayers.cs
Normal file
26
Campofinale/Commands/Handlers/CommandPlayers.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandPlayers
|
||||||
|
{
|
||||||
|
[Server.Command("players", "list of connected players", false)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "List of connected players:");
|
||||||
|
|
||||||
|
if (Server.clients.Count == 0) CommandManager.SendMessage(sender, "└No players on the server");
|
||||||
|
foreach (var player in Server.clients)
|
||||||
|
{
|
||||||
|
string decorator = "│";
|
||||||
|
if (player == Server.clients.Last()) decorator = "└";
|
||||||
|
|
||||||
|
CommandManager.SendMessage(sender, $"{decorator}Player: {player.nickname} | UID: {player.accountId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Campofinale/Commands/Handlers/CommandRemove.cs
Normal file
36
Campofinale/Commands/Handlers/CommandRemove.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers;
|
||||||
|
|
||||||
|
public static class CommandRemove
|
||||||
|
{
|
||||||
|
[Server.Command("remove", "Removes character", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if(args.Length < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /remove (char id)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Character character = target.chars.Find(c => c.id == args[0]);
|
||||||
|
if(character == null)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Character not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.chars.Remove(character);
|
||||||
|
DatabaseManager.db.DeleteCharacter(character);
|
||||||
|
target.SaveCharacters();
|
||||||
|
target.Send(new PacketScCharBagDelChar(target, character));
|
||||||
|
CommandManager.SendMessage(sender, $"Character {character.id} removed.");
|
||||||
|
}
|
||||||
|
}
|
56
Campofinale/Commands/Handlers/CommandSpawn.cs
Normal file
56
Campofinale/Commands/Handlers/CommandSpawn.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using Campofinale.Game.Entities;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandSpawn
|
||||||
|
{
|
||||||
|
[Server.Command("spawn", "Spawn command", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Example: spawn (id) (level)");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
string templateId = args[0];
|
||||||
|
int level = int.Parse(args[1]);
|
||||||
|
if (level < 1)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Level can't be less than 1");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (templateId.Split("_")[0])
|
||||||
|
{
|
||||||
|
case "eny":
|
||||||
|
if (ResourceManager.enemyTable.ContainsKey(templateId))
|
||||||
|
{
|
||||||
|
EntityMonster mon = new(templateId, level, target.roleId, target.position, target.rotation,target.curSceneNumId);
|
||||||
|
target.sceneManager.SpawnEntity(mon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Monster template id not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
|
||||||
|
CommandManager.SendMessage(sender, "Unsupported template id to spawn: " + templateId.Split("_")[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*target.Send(ScMessageId.ScSpawnEnemy, new ScSpawnEnemy()
|
||||||
|
{
|
||||||
|
ClientKey=2,
|
||||||
|
EnemyInstIds = { info.Detail.MonsterList[0].CommonInfo.Id }
|
||||||
|
});*/
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
Campofinale/Commands/Handlers/CommandTeleport.cs
Normal file
47
Campofinale/Commands/Handlers/CommandTeleport.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public class CommandTeleport
|
||||||
|
{
|
||||||
|
[Server.Command("tp", "Teleports player", true)]
|
||||||
|
public static void Handle(Player sender, string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
CommandManager.SendMessage(sender, "Use: /tp (x) (y) (z)\nYou can use ~ to use current player coordinate");
|
||||||
|
CommandManager.SendMessage(sender, $"\nCurrent player position: {target.position.ToJson()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i < args.Length; i++)
|
||||||
|
{
|
||||||
|
args[i] = Uri.UnescapeDataString(args[i]).Replace(".", ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
x = args[0] == "~" ? target.position.x : float.Parse(args[0]);
|
||||||
|
y = args[1] == "~" ? target.position.y : float.Parse(args[1]);
|
||||||
|
z = args[2] == "~" ? target.position.z : float.Parse(args[2]);
|
||||||
|
|
||||||
|
Vector3f position = new Vector3f(new Vector()
|
||||||
|
{
|
||||||
|
X = x,
|
||||||
|
Y = y,
|
||||||
|
Z = z
|
||||||
|
});
|
||||||
|
|
||||||
|
target.position = position;
|
||||||
|
target.Send(new PacketScEnterSceneNotify(target, target.curSceneNumId, position));
|
||||||
|
CommandManager.SendMessage(sender, $"Player teleported to {target.position.ToJson()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
Campofinale/Commands/Handlers/CommandUnlockAll.cs
Normal file
37
Campofinale/Commands/Handlers/CommandUnlockAll.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Commands.Handlers
|
||||||
|
{
|
||||||
|
public static class CommandUnlockAll
|
||||||
|
{
|
||||||
|
[Server.Command("unlockall", "Unlock all systems",true)]
|
||||||
|
public static void Handle(Player sender,string cmd, string[] args, Player target)
|
||||||
|
{
|
||||||
|
target.unlockedSystems.Clear();
|
||||||
|
target.UnlockImportantSystems();
|
||||||
|
target.maxDashEnergy = 250;
|
||||||
|
foreach (var system in target.unlockedSystems)
|
||||||
|
{
|
||||||
|
ScUnlockSystem unlocked = new()
|
||||||
|
{
|
||||||
|
UnlockSystemType = system,
|
||||||
|
};
|
||||||
|
target.Send(ScMsgId.ScUnlockSystem, unlocked);
|
||||||
|
}
|
||||||
|
foreach (int i in ResourceManager.GetAllShortIds())
|
||||||
|
{
|
||||||
|
target.bitsetManager.AddValue(BitsetType.InteractiveActive, i);
|
||||||
|
}
|
||||||
|
target.Send(new PacketScSyncAllBitset(target));
|
||||||
|
CommandManager.SendMessage(sender, "Unlocked everything");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
71
Campofinale/ConfigFile.cs
Normal file
71
Campofinale/ConfigFile.cs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale
|
||||||
|
{
|
||||||
|
public class ConfigFile
|
||||||
|
{
|
||||||
|
public MongoDatabaseSettings mongoDatabase = new();
|
||||||
|
public DispatchServerSettings dispatchServer = new();
|
||||||
|
public GameserverSettings gameServer = new();
|
||||||
|
public ServerOptions serverOptions = new();
|
||||||
|
public LogSettings logOptions = new();
|
||||||
|
}
|
||||||
|
public struct ServerOptions
|
||||||
|
{
|
||||||
|
public int defaultSceneNumId = 98;
|
||||||
|
public int maxPlayers = 20;
|
||||||
|
|
||||||
|
public ServerOptions()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* public struct WelcomeMail
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
public struct LogSettings
|
||||||
|
{
|
||||||
|
public bool packets;
|
||||||
|
public bool debugPrint=false;
|
||||||
|
|
||||||
|
public LogSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct GameserverSettings
|
||||||
|
{
|
||||||
|
public string bindAddress = "127.0.0.1";
|
||||||
|
public int bindPort = 30000;
|
||||||
|
public string accessAddress = "127.0.0.1";
|
||||||
|
public int accessPort = 30000;
|
||||||
|
public GameserverSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct DispatchServerSettings
|
||||||
|
{
|
||||||
|
public string bindAddress = "127.0.0.1";
|
||||||
|
|
||||||
|
public int bindPort = 5000;
|
||||||
|
public string accessAddress = "127.0.0.1";
|
||||||
|
public int accessPort = 5000;
|
||||||
|
public string emailFormat = "@campofinale.ps";
|
||||||
|
public DispatchServerSettings()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct MongoDatabaseSettings
|
||||||
|
{
|
||||||
|
public string uri = "mongodb://localhost:27017";
|
||||||
|
public string collection = "Campofinale";
|
||||||
|
public MongoDatabaseSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
930
Campofinale/Crypto/CSChaCha20.cs
Normal file
930
Campofinale/Crypto/CSChaCha20.cs
Normal file
@ -0,0 +1,930 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015, 2018 Scott Bennett
|
||||||
|
* (c) 2018-2023 Kaarlo Räihä
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.Intrinsics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace BeyondTools.VFS.Crypto;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Chosen SIMD mode
|
||||||
|
/// </summary>
|
||||||
|
public enum SimdMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Autodetect
|
||||||
|
/// </summary>
|
||||||
|
AutoDetect = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 128 bit SIMD
|
||||||
|
/// </summary>
|
||||||
|
V128,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 256 bit SIMD
|
||||||
|
/// </summary>
|
||||||
|
V256,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 512 bit SIMD
|
||||||
|
/// </summary>
|
||||||
|
V512,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// No SIMD
|
||||||
|
/// </summary>
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class for ChaCha20 encryption / decryption
|
||||||
|
/// </summary>
|
||||||
|
public sealed class CSChaCha20 : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Only allowed key lenght in bytes
|
||||||
|
/// </summary>
|
||||||
|
public const int allowedKeyLength = 32;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only allowed nonce lenght in bytes
|
||||||
|
/// </summary>
|
||||||
|
public const int allowedNonceLength = 12;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many bytes are processed per loop
|
||||||
|
/// </summary>
|
||||||
|
public const int processBytesAtTime = 64;
|
||||||
|
|
||||||
|
private const int stateLength = 16;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ChaCha20 state (aka "context")
|
||||||
|
/// </summary>
|
||||||
|
private readonly uint[] state = new uint[stateLength];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if the objects in this class have been disposed of. Set to true by the Dispose() method.
|
||||||
|
/// </summary>
|
||||||
|
private bool isDisposed = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set up a new ChaCha20 state. The lengths of the given parameters are checked before encryption happens.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// See <a href="https://tools.ietf.org/html/rfc7539#page-10">ChaCha20 Spec Section 2.4</a> for a detailed description of the inputs.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="key">
|
||||||
|
/// A 32-byte (256-bit) key, treated as a concatenation of eight 32-bit little-endian integers
|
||||||
|
/// </param>
|
||||||
|
/// <param name="nonce">
|
||||||
|
/// A 12-byte (96-bit) nonce, treated as a concatenation of three 32-bit little-endian integers
|
||||||
|
/// </param>
|
||||||
|
/// <param name="counter">
|
||||||
|
/// A 4-byte (32-bit) block counter, treated as a 32-bit little-endian integer
|
||||||
|
/// </param>
|
||||||
|
public CSChaCha20(byte[] key, byte[] nonce, uint counter)
|
||||||
|
{
|
||||||
|
KeySetup(key);
|
||||||
|
IvSetup(nonce, counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set up a new ChaCha20 state. The lengths of the given parameters are checked before encryption happens.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// See <a href="https://tools.ietf.org/html/rfc7539#page-10">ChaCha20 Spec Section 2.4</a> for a detailed description of the inputs.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="key">A 32-byte (256-bit) key, treated as a concatenation of eight 32-bit little-endian integers</param>
|
||||||
|
/// <param name="nonce">A 12-byte (96-bit) nonce, treated as a concatenation of three 32-bit little-endian integers</param>
|
||||||
|
/// <param name="counter">A 4-byte (32-bit) block counter, treated as a 32-bit little-endian unsigned integer</param>
|
||||||
|
public CSChaCha20(ReadOnlySpan<byte> key, ReadOnlySpan<byte> nonce, uint counter)
|
||||||
|
{
|
||||||
|
KeySetup(key.ToArray());
|
||||||
|
IvSetup(nonce.ToArray(), counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ChaCha20 state (aka "context"). Read-Only.
|
||||||
|
/// </summary>
|
||||||
|
public uint[] State
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// These are the same constants defined in the reference implementation.
|
||||||
|
// http://cr.yp.to/streamciphers/timings/estreambench/submissions/salsa20/chacha8/ref/chacha.c
|
||||||
|
private static readonly byte[] sigma = "expand 32-byte k"u8.ToArray();
|
||||||
|
private static readonly byte[] tau = "expand 16-byte k"u8.ToArray();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set up the ChaCha state with the given key. A 32-byte key is required and enforced.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">
|
||||||
|
/// A 32-byte (256-bit) key, treated as a concatenation of eight 32-bit little-endian integers
|
||||||
|
/// </param>
|
||||||
|
private void KeySetup(byte[] key)
|
||||||
|
{
|
||||||
|
if (key == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("Key is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.Length != allowedKeyLength)
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Key length must be {allowedKeyLength}. Actual: {key.Length}");
|
||||||
|
}
|
||||||
|
|
||||||
|
state[4] = Util.U8To32Little(key, 0);
|
||||||
|
state[5] = Util.U8To32Little(key, 4);
|
||||||
|
state[6] = Util.U8To32Little(key, 8);
|
||||||
|
state[7] = Util.U8To32Little(key, 12);
|
||||||
|
|
||||||
|
byte[] constants = key.Length == allowedKeyLength ? sigma : tau;
|
||||||
|
int keyIndex = key.Length - 16;
|
||||||
|
|
||||||
|
state[8] = Util.U8To32Little(key, keyIndex + 0);
|
||||||
|
state[9] = Util.U8To32Little(key, keyIndex + 4);
|
||||||
|
state[10] = Util.U8To32Little(key, keyIndex + 8);
|
||||||
|
state[11] = Util.U8To32Little(key, keyIndex + 12);
|
||||||
|
|
||||||
|
state[0] = Util.U8To32Little(constants, 0);
|
||||||
|
state[1] = Util.U8To32Little(constants, 4);
|
||||||
|
state[2] = Util.U8To32Little(constants, 8);
|
||||||
|
state[3] = Util.U8To32Little(constants, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set up the ChaCha state with the given nonce (aka Initialization Vector or IV) and block counter. A 12-byte nonce and a 4-byte counter are required.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="nonce">
|
||||||
|
/// A 12-byte (96-bit) nonce, treated as a concatenation of three 32-bit little-endian integers
|
||||||
|
/// </param>
|
||||||
|
/// <param name="counter">
|
||||||
|
/// A 4-byte (32-bit) block counter, treated as a 32-bit little-endian integer
|
||||||
|
/// </param>
|
||||||
|
private void IvSetup(byte[] nonce, uint counter)
|
||||||
|
{
|
||||||
|
if (nonce == null)
|
||||||
|
{
|
||||||
|
// There has already been some state set up. Clear it before exiting.
|
||||||
|
Dispose();
|
||||||
|
throw new ArgumentNullException("Nonce is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonce.Length != allowedNonceLength)
|
||||||
|
{
|
||||||
|
// There has already been some state set up. Clear it before exiting.
|
||||||
|
Dispose();
|
||||||
|
throw new ArgumentException($"Nonce length must be {allowedNonceLength}. Actual: {nonce.Length}");
|
||||||
|
}
|
||||||
|
|
||||||
|
state[12] = counter;
|
||||||
|
state[13] = Util.U8To32Little(nonce, 0);
|
||||||
|
state[14] = Util.U8To32Little(nonce, 4);
|
||||||
|
state[15] = Util.U8To32Little(nonce, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SimdMode DetectSimdMode()
|
||||||
|
{
|
||||||
|
if (Vector512.IsHardwareAccelerated)
|
||||||
|
{
|
||||||
|
return SimdMode.V512;
|
||||||
|
}
|
||||||
|
else if (Vector256.IsHardwareAccelerated)
|
||||||
|
{
|
||||||
|
return SimdMode.V256;
|
||||||
|
}
|
||||||
|
else if (Vector128.IsHardwareAccelerated)
|
||||||
|
{
|
||||||
|
return SimdMode.V128;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SimdMode.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Encryption methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt arbitrary-length byte array (input), writing the resulting byte array to preallocated output buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="output">Output byte array, must have enough bytes</param>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="numBytes">Number of bytes to encrypt</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void EncryptBytes(byte[] output, byte[] input, int numBytes, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (output == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("output", "Output cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes < 0 || numBytes > input.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("numBytes", "The number of bytes to read must be between [0..input.Length]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.Length < numBytes)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("output", $"Output byte array should be able to take at least {numBytes}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkBytes(output, input, numBytes, simdMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt arbitrary-length byte stream (input), writing the resulting bytes to another stream (output)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output">Output stream</param>
|
||||||
|
/// <param name="input">Input stream</param>
|
||||||
|
/// <param name="howManyBytesToProcessAtTime">How many bytes to read and write at time, default is 1024</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void EncryptStream(Stream output, Stream input, int howManyBytesToProcessAtTime = 1024, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkStreams(output, input, simdMode, howManyBytesToProcessAtTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Async encrypt arbitrary-length byte stream (input), writing the resulting bytes to another stream (output)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output">Output stream</param>
|
||||||
|
/// <param name="input">Input stream</param>
|
||||||
|
/// <param name="howManyBytesToProcessAtTime">How many bytes to read and write at time, default is 1024</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public async Task EncryptStreamAsync(Stream output, Stream input, int howManyBytesToProcessAtTime = 1024, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
await WorkStreamsAsync(output, input, simdMode, howManyBytesToProcessAtTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt arbitrary-length byte array (input), writing the resulting byte array to preallocated output buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="output">Output byte array, must have enough bytes</param>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void EncryptBytes(byte[] output, byte[] input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (output == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("output", "Output cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkBytes(output, input, input.Length, simdMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt arbitrary-length byte array (input), writing the resulting byte array that is allocated by method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="numBytes">Number of bytes to encrypt</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains encrypted bytes</returns>
|
||||||
|
public byte[] EncryptBytes(byte[] input, int numBytes, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes < 0 || numBytes > input.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("numBytes", "The number of bytes to read must be between [0..input.Length]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] returnArray = new byte[numBytes];
|
||||||
|
WorkBytes(returnArray, input, numBytes, simdMode);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt arbitrary-length byte array (input), writing the resulting byte array that is allocated by method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains encrypted bytes</returns>
|
||||||
|
public byte[] EncryptBytes(byte[] input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] returnArray = new byte[input.Length];
|
||||||
|
WorkBytes(returnArray, input, input.Length, simdMode);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt string as UTF8 byte array, returns byte array that is allocated by method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Here you can NOT swap encrypt and decrypt methods, because of bytes-string transform</remarks>
|
||||||
|
/// <param name="input">Input string</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains encrypted bytes</returns>
|
||||||
|
public byte[] EncryptString(string input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(input);
|
||||||
|
byte[] returnArray = new byte[utf8Bytes.Length];
|
||||||
|
|
||||||
|
WorkBytes(returnArray, utf8Bytes, utf8Bytes.Length, simdMode);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Encryption methods
|
||||||
|
|
||||||
|
|
||||||
|
#region // Decryption methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt arbitrary-length byte array (input), writing the resulting byte array to the output buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="output">Output byte array</param>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="numBytes">Number of bytes to decrypt</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void DecryptBytes(byte[] output, byte[] input, int numBytes, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (output == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("output", "Output cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes < 0 || numBytes > input.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("numBytes", "The number of bytes to read must be between [0..input.Length]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.Length < numBytes)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("output", $"Output byte array should be able to take at least {numBytes}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkBytes(output, input, numBytes, simdMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt arbitrary-length byte stream (input), writing the resulting bytes to another stream (output)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output">Output stream</param>
|
||||||
|
/// <param name="input">Input stream</param>
|
||||||
|
/// <param name="howManyBytesToProcessAtTime">How many bytes to read and write at time, default is 1024</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void DecryptStream(Stream output, Stream input, int howManyBytesToProcessAtTime = 1024, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkStreams(output, input, simdMode, howManyBytesToProcessAtTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Async decrypt arbitrary-length byte stream (input), writing the resulting bytes to another stream (output)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output">Output stream</param>
|
||||||
|
/// <param name="input">Input stream</param>
|
||||||
|
/// <param name="howManyBytesToProcessAtTime">How many bytes to read and write at time, default is 1024</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public async Task DecryptStreamAsync(Stream output, Stream input, int howManyBytesToProcessAtTime = 1024, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
await WorkStreamsAsync(output, input, simdMode, howManyBytesToProcessAtTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt arbitrary-length byte array (input), writing the resulting byte array to preallocated output buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="output">Output byte array, must have enough bytes</param>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
public void DecryptBytes(byte[] output, byte[] input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (output == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("output", "Output cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
WorkBytes(output, input, input.Length, simdMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt arbitrary-length byte array (input), writing the resulting byte array that is allocated by method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="numBytes">Number of bytes to encrypt</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains decrypted bytes</returns>
|
||||||
|
public byte[] DecryptBytes(byte[] input, int numBytes, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numBytes < 0 || numBytes > input.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("numBytes", "The number of bytes to read must be between [0..input.Length]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] returnArray = new byte[numBytes];
|
||||||
|
WorkBytes(returnArray, input, numBytes, simdMode);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt arbitrary-length byte array (input), writing the resulting byte array that is allocated by method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Since this is symmetric operation, it doesn't really matter if you use Encrypt or Decrypt method</remarks>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains decrypted bytes</returns>
|
||||||
|
public byte[] DecryptBytes(byte[] input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] returnArray = new byte[input.Length];
|
||||||
|
WorkBytes(returnArray, input, input.Length, simdMode);
|
||||||
|
return returnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decrypt UTF8 byte array to string.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>Here you can NOT swap encrypt and decrypt methods, because of bytes-string transform</remarks>
|
||||||
|
/// <param name="input">Byte array</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
/// <returns>Byte array that contains encrypted bytes</returns>
|
||||||
|
public string DecryptUTF8ByteArray(byte[] input, SimdMode simdMode = SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("input", "Input cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.AutoDetect)
|
||||||
|
{
|
||||||
|
simdMode = DetectSimdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] tempArray = new byte[input.Length];
|
||||||
|
|
||||||
|
WorkBytes(tempArray, input, input.Length, simdMode);
|
||||||
|
return System.Text.Encoding.UTF8.GetString(tempArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Decryption methods
|
||||||
|
|
||||||
|
private void WorkStreams(Stream output, Stream input, SimdMode simdMode, int howManyBytesToProcessAtTime = 1024)
|
||||||
|
{
|
||||||
|
int readBytes;
|
||||||
|
|
||||||
|
byte[] inputBuffer = new byte[howManyBytesToProcessAtTime];
|
||||||
|
byte[] outputBuffer = new byte[howManyBytesToProcessAtTime];
|
||||||
|
|
||||||
|
while ((readBytes = input.Read(inputBuffer, 0, howManyBytesToProcessAtTime)) > 0)
|
||||||
|
{
|
||||||
|
// Encrypt or decrypt
|
||||||
|
WorkBytes(output: outputBuffer, input: inputBuffer, numBytes: readBytes, simdMode);
|
||||||
|
|
||||||
|
// Write buffer
|
||||||
|
output.Write(outputBuffer, 0, readBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task WorkStreamsAsync(Stream output, Stream input, SimdMode simdMode, int howManyBytesToProcessAtTime = 1024)
|
||||||
|
{
|
||||||
|
byte[] readBytesBuffer = new byte[howManyBytesToProcessAtTime];
|
||||||
|
byte[] writeBytesBuffer = new byte[howManyBytesToProcessAtTime];
|
||||||
|
int howManyBytesWereRead = await input.ReadAsync(readBytesBuffer, 0, howManyBytesToProcessAtTime);
|
||||||
|
|
||||||
|
while (howManyBytesWereRead > 0)
|
||||||
|
{
|
||||||
|
// Encrypt or decrypt
|
||||||
|
WorkBytes(output: writeBytesBuffer, input: readBytesBuffer, numBytes: howManyBytesWereRead, simdMode);
|
||||||
|
|
||||||
|
// Write
|
||||||
|
await output.WriteAsync(writeBytesBuffer, 0, howManyBytesWereRead);
|
||||||
|
|
||||||
|
// Read more
|
||||||
|
howManyBytesWereRead = await input.ReadAsync(readBytesBuffer, 0, howManyBytesToProcessAtTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypt or decrypt an arbitrary-length byte array (input), writing the resulting byte array to the output buffer. The number of bytes to read from the input buffer is determined by numBytes.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output">Output byte array</param>
|
||||||
|
/// <param name="input">Input byte array</param>
|
||||||
|
/// <param name="numBytes">How many bytes to process</param>
|
||||||
|
/// <param name="simdMode">Chosen SIMD mode (default is auto-detect)</param>
|
||||||
|
private void WorkBytes(byte[] output, byte[] input, int numBytes, SimdMode simdMode)
|
||||||
|
{
|
||||||
|
if (isDisposed)
|
||||||
|
{
|
||||||
|
throw new ObjectDisposedException("state", "The ChaCha state has been disposed");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint[] x = new uint[stateLength]; // Working buffer
|
||||||
|
byte[] tmp = new byte[processBytesAtTime]; // Temporary buffer
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
int howManyFullLoops = numBytes / processBytesAtTime;
|
||||||
|
int tailByteCount = numBytes - howManyFullLoops * processBytesAtTime;
|
||||||
|
|
||||||
|
for (int loop = 0; loop < howManyFullLoops; loop++)
|
||||||
|
{
|
||||||
|
UpdateStateAndGenerateTemporaryBuffer(state, x, tmp);
|
||||||
|
|
||||||
|
if (simdMode == SimdMode.V512)
|
||||||
|
{
|
||||||
|
// 1 x 64 bytes
|
||||||
|
Vector512<byte> inputV = Vector512.Create(input, offset);
|
||||||
|
Vector512<byte> tmpV = Vector512.Create(tmp, 0);
|
||||||
|
Vector512<byte> outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset);
|
||||||
|
}
|
||||||
|
else if (simdMode == SimdMode.V256)
|
||||||
|
{
|
||||||
|
// 2 x 32 bytes
|
||||||
|
Vector256<byte> inputV = Vector256.Create(input, offset);
|
||||||
|
Vector256<byte> tmpV = Vector256.Create(tmp, 0);
|
||||||
|
Vector256<byte> outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset);
|
||||||
|
|
||||||
|
inputV = Vector256.Create(input, offset + 32);
|
||||||
|
tmpV = Vector256.Create(tmp, 32);
|
||||||
|
outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset + 32);
|
||||||
|
}
|
||||||
|
else if (simdMode == SimdMode.V128)
|
||||||
|
{
|
||||||
|
// 4 x 16 bytes
|
||||||
|
Vector128<byte> inputV = Vector128.Create(input, offset);
|
||||||
|
Vector128<byte> tmpV = Vector128.Create(tmp, 0);
|
||||||
|
Vector128<byte> outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset);
|
||||||
|
|
||||||
|
inputV = Vector128.Create(input, offset + 16);
|
||||||
|
tmpV = Vector128.Create(tmp, 16);
|
||||||
|
outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset + 16);
|
||||||
|
|
||||||
|
inputV = Vector128.Create(input, offset + 32);
|
||||||
|
tmpV = Vector128.Create(tmp, 32);
|
||||||
|
outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset + 32);
|
||||||
|
|
||||||
|
inputV = Vector128.Create(input, offset + 48);
|
||||||
|
tmpV = Vector128.Create(tmp, 48);
|
||||||
|
outputV = inputV ^ tmpV;
|
||||||
|
outputV.CopyTo(output, offset + 48);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < processBytesAtTime; i += 4)
|
||||||
|
{
|
||||||
|
// Small unroll
|
||||||
|
int start = i + offset;
|
||||||
|
output[start] = (byte)(input[start] ^ tmp[i]);
|
||||||
|
output[start + 1] = (byte)(input[start + 1] ^ tmp[i + 1]);
|
||||||
|
output[start + 2] = (byte)(input[start + 2] ^ tmp[i + 2]);
|
||||||
|
output[start + 3] = (byte)(input[start + 3] ^ tmp[i + 3]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += processBytesAtTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In case there are some bytes left
|
||||||
|
if (tailByteCount > 0)
|
||||||
|
{
|
||||||
|
UpdateStateAndGenerateTemporaryBuffer(state, x, tmp);
|
||||||
|
|
||||||
|
for (int i = 0; i < tailByteCount; i++)
|
||||||
|
{
|
||||||
|
output[i + offset] = (byte)(input[i + offset] ^ tmp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static void UpdateStateAndGenerateTemporaryBuffer(uint[] stateToModify, uint[] workingBuffer, byte[] temporaryBuffer)
|
||||||
|
{
|
||||||
|
// Copy state to working buffer
|
||||||
|
Buffer.BlockCopy(stateToModify, 0, workingBuffer, 0, stateLength * sizeof(uint));
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
QuarterRound(workingBuffer, 0, 4, 8, 12);
|
||||||
|
QuarterRound(workingBuffer, 1, 5, 9, 13);
|
||||||
|
QuarterRound(workingBuffer, 2, 6, 10, 14);
|
||||||
|
QuarterRound(workingBuffer, 3, 7, 11, 15);
|
||||||
|
|
||||||
|
QuarterRound(workingBuffer, 0, 5, 10, 15);
|
||||||
|
QuarterRound(workingBuffer, 1, 6, 11, 12);
|
||||||
|
QuarterRound(workingBuffer, 2, 7, 8, 13);
|
||||||
|
QuarterRound(workingBuffer, 3, 4, 9, 14);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < stateLength; i++)
|
||||||
|
{
|
||||||
|
Util.ToBytes(temporaryBuffer, Util.Add(workingBuffer[i], stateToModify[i]), 4 * i);
|
||||||
|
}
|
||||||
|
|
||||||
|
stateToModify[12] = Util.AddOne(stateToModify[12]);
|
||||||
|
if (stateToModify[12] <= 0)
|
||||||
|
{
|
||||||
|
/* Stopping at 2^70 bytes per nonce is the user's responsibility */
|
||||||
|
stateToModify[13] = Util.AddOne(stateToModify[13]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ChaCha Quarter Round operation. It operates on four 32-bit unsigned integers within the given buffer at indices a, b, c, and d.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The ChaCha state does not have four integer numbers: it has 16. So the quarter-round operation works on only four of them -- hence the name. Each quarter round operates on four predetermined numbers in the ChaCha state.
|
||||||
|
/// See <a href="https://tools.ietf.org/html/rfc7539#page-4">ChaCha20 Spec Sections 2.1 - 2.2</a>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="x">A ChaCha state (vector). Must contain 16 elements.</param>
|
||||||
|
/// <param name="a">Index of the first number</param>
|
||||||
|
/// <param name="b">Index of the second number</param>
|
||||||
|
/// <param name="c">Index of the third number</param>
|
||||||
|
/// <param name="d">Index of the fourth number</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private static void QuarterRound(uint[] x, uint a, uint b, uint c, uint d)
|
||||||
|
{
|
||||||
|
x[a] = Util.Add(x[a], x[b]);
|
||||||
|
x[d] = Util.Rotate(Util.XOr(x[d], x[a]), 16);
|
||||||
|
|
||||||
|
x[c] = Util.Add(x[c], x[d]);
|
||||||
|
x[b] = Util.Rotate(Util.XOr(x[b], x[c]), 12);
|
||||||
|
|
||||||
|
x[a] = Util.Add(x[a], x[b]);
|
||||||
|
x[d] = Util.Rotate(Util.XOr(x[d], x[a]), 8);
|
||||||
|
|
||||||
|
x[c] = Util.Add(x[c], x[d]);
|
||||||
|
x[b] = Util.Rotate(Util.XOr(x[b], x[c]), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Destructor and Disposer
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear and dispose of the internal state. The finalizer is only called if Dispose() was never called on this cipher.
|
||||||
|
/// </summary>
|
||||||
|
~CSChaCha20()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clear and dispose of the internal state. Also request the GC not to call the finalizer, because all cleanup has been taken care of.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
/*
|
||||||
|
* The Garbage Collector does not need to invoke the finalizer because Dispose(bool) has already done all the cleanup needed.
|
||||||
|
*/
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This method should only be invoked from Dispose() or the finalizer. This handles the actual cleanup of the resources.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">
|
||||||
|
/// Should be true if called by Dispose(); false if called by the finalizer
|
||||||
|
/// </param>
|
||||||
|
private void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (!isDisposed)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
/* Cleanup managed objects by calling their Dispose() methods */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cleanup any unmanaged objects here */
|
||||||
|
Array.Clear(state, 0, stateLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
isDisposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // Destructor and Disposer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Utilities that are used during compression
|
||||||
|
/// </summary>
|
||||||
|
public static class Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// n-bit left rotation operation (towards the high bits) for 32-bit integers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v"></param>
|
||||||
|
/// <param name="c"></param>
|
||||||
|
/// <returns>The result of (v LEFTSHIFT c)</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint Rotate(uint v, int c)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
return v << c | v >> 32 - c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unchecked integer exclusive or (XOR) operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v"></param>
|
||||||
|
/// <param name="w"></param>
|
||||||
|
/// <returns>The result of (v XOR w)</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint XOr(uint v, uint w)
|
||||||
|
{
|
||||||
|
return unchecked(v ^ w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Unchecked integer addition. The ChaCha spec defines certain operations to use 32-bit unsigned integer addition modulo 2^32.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// See <a href="https://tools.ietf.org/html/rfc7539#page-4">ChaCha20 Spec Section 2.1</a>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="v"></param>
|
||||||
|
/// <param name="w"></param>
|
||||||
|
/// <returns>The result of (v + w) modulo 2^32</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint Add(uint v, uint w)
|
||||||
|
{
|
||||||
|
return unchecked(v + w);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add 1 to the input parameter using unchecked integer addition. The ChaCha spec defines certain operations to use 32-bit unsigned integer addition modulo 2^32.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// See <a href="https://tools.ietf.org/html/rfc7539#page-4">ChaCha20 Spec Section 2.1</a>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="v"></param>
|
||||||
|
/// <returns>The result of (v + 1) modulo 2^32</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint AddOne(uint v)
|
||||||
|
{
|
||||||
|
return unchecked(v + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert four bytes of the input buffer into an unsigned 32-bit integer, beginning at the inputOffset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="p"></param>
|
||||||
|
/// <param name="inputOffset"></param>
|
||||||
|
/// <returns>An unsigned 32-bit integer</returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static uint U8To32Little(byte[] p, int inputOffset)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
return p[inputOffset]
|
||||||
|
| (uint)p[inputOffset + 1] << 8
|
||||||
|
| (uint)p[inputOffset + 2] << 16
|
||||||
|
| (uint)p[inputOffset + 3] << 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Serialize the input integer into the output buffer. The input integer will be split into 4 bytes and put into four sequential places in the output buffer, starting at the outputOffset.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="output"></param>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <param name="outputOffset"></param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void ToBytes(byte[] output, uint input, int outputOffset)
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
output[outputOffset] = (byte)input;
|
||||||
|
output[outputOffset + 1] = (byte)(input >> 8);
|
||||||
|
output[outputOffset + 2] = (byte)(input >> 16);
|
||||||
|
output[outputOffset + 3] = (byte)(input >> 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
225
Campofinale/Data/GachaHistory/index.html
Normal file
225
Campofinale/Data/GachaHistory/index.html
Normal file
File diff suppressed because one or more lines are too long
116
Campofinale/Data/GachaHistory/index_noplayerfound.html
Normal file
116
Campofinale/Data/GachaHistory/index_noplayerfound.html
Normal file
File diff suppressed because one or more lines are too long
191
Campofinale/Data/PlayerConsole/index.html
Normal file
191
Campofinale/Data/PlayerConsole/index.html
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-US">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=0,initial-scale=1">
|
||||||
|
<meta name="keywords" content="">
|
||||||
|
<meta name="description" content="Player Console">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="Player Console">
|
||||||
|
<meta property="og:description" content="Player Console">
|
||||||
|
<title>Player Console</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
font-family: endfieldFont;
|
||||||
|
background-image: url("cs_bg.jpg");
|
||||||
|
background-size: cover;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: endfieldFont;
|
||||||
|
src: url("/ja-jp.otf");
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 30px;
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
border-bottom: 2px solid #7a7a7a;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-grow: 1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#console-output {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 20px;
|
||||||
|
color: rgb(39, 39, 39);
|
||||||
|
}
|
||||||
|
|
||||||
|
#console-input {
|
||||||
|
display: flex;
|
||||||
|
padding: 10px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#command-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#send-button {
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin-left: 10px;
|
||||||
|
background-color: #fdfd1f;
|
||||||
|
color: black;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#send-button:hover {
|
||||||
|
background-color: #caca1c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-family: monospace;
|
||||||
|
background-color: rgba(255, 255, 255, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.user {
|
||||||
|
background-color: rgba(231, 243, 255, 0.6);
|
||||||
|
color: #1c3f95;
|
||||||
|
border-left: 5px solid #1c3f95;
|
||||||
|
}
|
||||||
|
|
||||||
|
.server {
|
||||||
|
background-color: rgba(255, 246, 224, 0.6);
|
||||||
|
color: #b8860b;
|
||||||
|
border-left: 5px solid #b8860b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background-color: rgba(255, 204, 204, 0.6);
|
||||||
|
color: #a80000;
|
||||||
|
border-left: 5px solid #a80000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="root">
|
||||||
|
<div class="header">//Command Prompt</div>
|
||||||
|
<div id="console-output"></div>
|
||||||
|
<div id="console-input">
|
||||||
|
<input type="text" id="command-input" placeholder="Enter command..." />
|
||||||
|
<button id="send-button">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const consoleOutput = document.getElementById('console-output');
|
||||||
|
const commandInput = document.getElementById('command-input');
|
||||||
|
const sendButton = document.getElementById('send-button');
|
||||||
|
|
||||||
|
function renderMarkdown(text) {
|
||||||
|
// Simple markdown conversion (bold, italics, new lines)
|
||||||
|
return text
|
||||||
|
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||||||
|
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
||||||
|
.replace(/\n/g, '<br>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMessage(type, text) {
|
||||||
|
const messageElement = document.createElement('div');
|
||||||
|
messageElement.classList.add('message', type);
|
||||||
|
messageElement.innerHTML = renderMarkdown(text);
|
||||||
|
consoleOutput.appendChild(messageElement);
|
||||||
|
consoleOutput.scrollTop = consoleOutput.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sendCommand(command) {
|
||||||
|
if (!command.trim()) return;
|
||||||
|
|
||||||
|
addMessage('user', `**User:** ${command}`);
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const token = urlParams.get('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = new URL('%dispatchip%/pcSdk/console');
|
||||||
|
url.searchParams.append('command', command);
|
||||||
|
url.searchParams.append('token', token);
|
||||||
|
|
||||||
|
const response = await fetch(url.toString(), {
|
||||||
|
method: 'GET',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Server responded with status ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
addMessage('server', `**Server:** ${data.message}`);
|
||||||
|
} catch (error) {
|
||||||
|
addMessage('error', `**Error:** ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendButton.addEventListener('click', () => {
|
||||||
|
const command = commandInput.value;
|
||||||
|
commandInput.value = '';
|
||||||
|
sendCommand(command);
|
||||||
|
});
|
||||||
|
|
||||||
|
commandInput.addEventListener('keypress', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
const command = commandInput.value;
|
||||||
|
commandInput.value = '';
|
||||||
|
sendCommand(command);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
BIN
Campofinale/Data/Static/bar.jpg
Normal file
BIN
Campofinale/Data/Static/bar.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
Campofinale/Data/Static/bg.jpg
Normal file
BIN
Campofinale/Data/Static/bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
BIN
Campofinale/Data/Static/cs_bg.jpg
Normal file
BIN
Campofinale/Data/Static/cs_bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 71 KiB |
BIN
Campofinale/Data/Static/ja-jp.otf
Normal file
BIN
Campofinale/Data/Static/ja-jp.otf
Normal file
Binary file not shown.
378
Campofinale/Database/Database.cs
Normal file
378
Campofinale/Database/Database.cs
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
using Campofinale.Game;
|
||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Game.Gacha;
|
||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
using Campofinale.Game.Spaceship;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Player;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static SQLite.SQLite3;
|
||||||
|
|
||||||
|
namespace Campofinale.Database
|
||||||
|
{
|
||||||
|
public class PlayerData
|
||||||
|
{
|
||||||
|
[BsonId]
|
||||||
|
public ulong roleId;
|
||||||
|
|
||||||
|
public string accountId;
|
||||||
|
public Vector3f position;
|
||||||
|
public Vector3f rotation;
|
||||||
|
public int curSceneNumId;
|
||||||
|
public uint level = 20;
|
||||||
|
public uint xp = 0;
|
||||||
|
public string nickname = "Endministrator";
|
||||||
|
public int teamIndex = 0;
|
||||||
|
public List<Team> teams = new List<Team>();
|
||||||
|
public ulong totalGuidCount = 1;
|
||||||
|
public List<int> unlockedSystems = new();
|
||||||
|
public List<ulong> noSpawnAnymore = new();
|
||||||
|
public long maxDashEnergy = 250;
|
||||||
|
public uint curStamina;
|
||||||
|
public long nextRecoverTime;
|
||||||
|
public List<Scene> scenes = new();
|
||||||
|
public Dictionary<int, List<int>> bitsets = new();
|
||||||
|
public PlayerSafeZoneInfo savedSafeZone = new();
|
||||||
|
}
|
||||||
|
public class Account
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public string username;
|
||||||
|
public string token;
|
||||||
|
public string grantToken;
|
||||||
|
|
||||||
|
public static string GenerateAccountId()
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[4];
|
||||||
|
RandomNumberGenerator.Fill(bytes);
|
||||||
|
|
||||||
|
// Converte i byte in un intero positivo tra 100000000 e 999999999
|
||||||
|
int number = BitConverter.ToInt32(bytes, 0) & int.MaxValue;
|
||||||
|
number = 100000000 + (number % 900000000);
|
||||||
|
|
||||||
|
return number.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Database
|
||||||
|
{
|
||||||
|
private readonly IMongoDatabase _database;
|
||||||
|
|
||||||
|
public Database(string connectionString, string dbName)
|
||||||
|
{
|
||||||
|
var client = new MongoClient(connectionString);
|
||||||
|
_database = client.GetDatabase(dbName);
|
||||||
|
}
|
||||||
|
public List<Mail> LoadMails(ulong roleId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Mail>("mails").Find(c => c.owner == roleId).ToList();
|
||||||
|
}
|
||||||
|
public List<Character> LoadCharacters(ulong roleId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Character>("avatars").Find(c=>c.owner== roleId).ToList();
|
||||||
|
}
|
||||||
|
public List<SpaceshipChar> LoadSpaceshipChars(ulong roleId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<SpaceshipChar>("spaceship_chars").Find(c => c.owner == roleId).ToList();
|
||||||
|
}
|
||||||
|
public List<SpaceshipRoom> LoadSpaceshipRooms(ulong roleId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<SpaceshipRoom>("spaceship_rooms").Find(c => c.owner == roleId).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Item> LoadInventoryItems(ulong roleId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Item>("items").Find(c => c.owner == roleId).ToList();
|
||||||
|
}
|
||||||
|
public void AddGachaTransaction(GachaTransaction transaction)
|
||||||
|
{
|
||||||
|
if (transaction._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
transaction._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<GachaTransaction>("gachas");
|
||||||
|
//These transactions never need to be changed
|
||||||
|
collection.InsertOne(transaction);
|
||||||
|
}
|
||||||
|
public List<GachaTransaction> LoadGachaTransaction(ulong roleId, string templateId)
|
||||||
|
{
|
||||||
|
return _database.GetCollection<GachaTransaction>("gachas").Find(c => c.ownerId== roleId && c.gachaTemplateId==templateId).ToList();
|
||||||
|
}
|
||||||
|
public static string GenerateToken(int length)
|
||||||
|
{
|
||||||
|
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
Random random = new Random();
|
||||||
|
StringBuilder result = new StringBuilder(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
result.Append(chars[random.Next(chars.Length)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
public void SavePlayerData(Player player)
|
||||||
|
{
|
||||||
|
PlayerData data = new()
|
||||||
|
{
|
||||||
|
accountId = player.accountId,
|
||||||
|
curSceneNumId = player.curSceneNumId,
|
||||||
|
level = player.level,
|
||||||
|
nickname = player.nickname,
|
||||||
|
position = player.position,
|
||||||
|
rotation = player.rotation,
|
||||||
|
roleId = player.roleId,
|
||||||
|
teams = player.teams,
|
||||||
|
xp = player.xp,
|
||||||
|
totalGuidCount = player.random.v,
|
||||||
|
teamIndex = player.teamIndex,
|
||||||
|
unlockedSystems = player.unlockedSystems,
|
||||||
|
maxDashEnergy = player.maxDashEnergy,
|
||||||
|
curStamina = player.curStamina,
|
||||||
|
nextRecoverTime = player.nextRecoverTime,
|
||||||
|
noSpawnAnymore = player.noSpawnAnymore,
|
||||||
|
scenes=player.sceneManager.scenes,
|
||||||
|
bitsets=player.bitsetManager.bitsets,
|
||||||
|
savedSafeZone = player.savedSaveZone
|
||||||
|
};
|
||||||
|
UpsertPlayerData(data);
|
||||||
|
}
|
||||||
|
public (string,int) CreateAccount(string username)
|
||||||
|
{
|
||||||
|
Account exist = GetAccountByUsername(username);
|
||||||
|
if (exist != null)
|
||||||
|
{
|
||||||
|
Logger.Print($"Cannot created account with username: {username} beecause it already exist.");
|
||||||
|
return ($"Cannot created account with username: {username} beecause it already exist.",1);
|
||||||
|
}
|
||||||
|
Account account = new()
|
||||||
|
{
|
||||||
|
username = username,
|
||||||
|
id = Account.GenerateAccountId(),
|
||||||
|
token= GenerateToken(22),
|
||||||
|
grantToken = GenerateToken(192)
|
||||||
|
};
|
||||||
|
UpsertAccount(account);
|
||||||
|
Logger.Print($"Account with username: {username} created with Account UID: {account.id}");
|
||||||
|
return ($"Account with username: {username} created with Account UID: {account.id}",0);
|
||||||
|
}
|
||||||
|
public void UpsertPlayerData(PlayerData player)
|
||||||
|
{
|
||||||
|
var collection = _database.GetCollection<PlayerData>("players");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<PlayerData>.Filter.Eq(p => p.roleId,player.roleId)
|
||||||
|
&
|
||||||
|
Builders<PlayerData>.Filter.Eq(p => p.accountId, player.accountId);
|
||||||
|
|
||||||
|
collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
player,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertAccount(Account player)
|
||||||
|
{
|
||||||
|
var collection = _database.GetCollection<Account>("accounts");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Account>.Filter.Eq(p => p.id, player.id)
|
||||||
|
&
|
||||||
|
Builders<Account>.Filter.Eq(p => p.token, player.token);
|
||||||
|
|
||||||
|
collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
player,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertSpaceshipChar(SpaceshipChar character)
|
||||||
|
{
|
||||||
|
if (character._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
character._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<SpaceshipChar>("spaceship_chars");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<SpaceshipChar>.Filter.Eq(c => c.id, character.id)
|
||||||
|
&
|
||||||
|
Builders<SpaceshipChar>.Filter.Eq(c => c.owner, character.owner);
|
||||||
|
|
||||||
|
var result = collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
character,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertSpaceshipRoom(SpaceshipRoom room)
|
||||||
|
{
|
||||||
|
if (room._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
room._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<SpaceshipRoom>("spaceship_rooms");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<SpaceshipRoom>.Filter.Eq(c => c.id, room.id)
|
||||||
|
&
|
||||||
|
Builders<SpaceshipRoom>.Filter.Eq(c => c.owner, room.owner);
|
||||||
|
|
||||||
|
var result = collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
room,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertCharacter(Character character)
|
||||||
|
{
|
||||||
|
if (character._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
character._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<Character>("avatars");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Character>.Filter.Eq(c => c.guid, character.guid)
|
||||||
|
&
|
||||||
|
Builders<Character>.Filter.Eq(c => c.owner, character.owner);
|
||||||
|
|
||||||
|
var result=collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
character,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertMail(Mail mail)
|
||||||
|
{
|
||||||
|
if (mail._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
mail._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<Mail>("mails");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Mail>.Filter.Eq(c => c.guid, mail.guid)
|
||||||
|
&
|
||||||
|
Builders<Mail>.Filter.Eq(c => c.owner, mail.owner);
|
||||||
|
|
||||||
|
var result = collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
mail,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void UpsertItem(Item item)
|
||||||
|
{
|
||||||
|
if (item._id == ObjectId.Empty)
|
||||||
|
{
|
||||||
|
item._id = ObjectId.GenerateNewId();
|
||||||
|
}
|
||||||
|
var collection = _database.GetCollection<Item>("items");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Item>.Filter.Eq(c => c.guid, item.guid)
|
||||||
|
&
|
||||||
|
Builders<Item>.Filter.Eq(c => c.owner, item.owner);
|
||||||
|
|
||||||
|
var result = collection.ReplaceOne(
|
||||||
|
filter,
|
||||||
|
item,
|
||||||
|
new ReplaceOptions { IsUpsert = true }
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
public void DeleteItem(Item item)
|
||||||
|
{
|
||||||
|
|
||||||
|
var collection = _database.GetCollection<Item>("items");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Item>.Filter.Eq(c => c.guid, item.guid)
|
||||||
|
&
|
||||||
|
Builders<Item>.Filter.Eq(c => c.owner, item.owner);
|
||||||
|
|
||||||
|
var result = collection.DeleteOne(
|
||||||
|
filter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public void DeleteCharacter(Character character)
|
||||||
|
{
|
||||||
|
|
||||||
|
var collection = _database.GetCollection<Character>("avatars");
|
||||||
|
|
||||||
|
var filter =
|
||||||
|
Builders<Character>.Filter.Eq(c => c.guid, character.guid)
|
||||||
|
&
|
||||||
|
Builders<Character>.Filter.Eq(c => c.owner, character.owner);
|
||||||
|
|
||||||
|
var result = collection.DeleteOne(
|
||||||
|
filter
|
||||||
|
);
|
||||||
|
}
|
||||||
|
public string GrantCode(Account account)
|
||||||
|
{
|
||||||
|
account.grantToken = GenerateToken(192);
|
||||||
|
UpsertAccount(account);
|
||||||
|
return account.grantToken;
|
||||||
|
}
|
||||||
|
public Account GetAccountByToken(string token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Account>("accounts").Find(p => p.token == token).ToList().FirstOrDefault();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError("Error: " + e.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Account GetAccountByTokenGrant(string token)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Account>("accounts").Find(p => p.grantToken == token).ToList().FirstOrDefault();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError("Error: " + e.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Account GetAccountByUsername(string username)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _database.GetCollection<Account>("accounts").Find(p => p.username == username).ToList().FirstOrDefault();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError("Error: "+e.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public PlayerData GetPlayerById(string id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _database.GetCollection<PlayerData>("players").Find(p => p.accountId == id).ToList().FirstOrDefault();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError("Error occured while loading Player with account id: " + id+" ERROR:\n"+e.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
101
Campofinale/Database/DatabaseManager.cs
Normal file
101
Campofinale/Database/DatabaseManager.cs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Serializers;
|
||||||
|
using MongoDB.Bson.Serialization;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson.IO;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System.Reflection;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Database
|
||||||
|
{
|
||||||
|
public class CustomDictionarySerializer<TKey, TValue> : IBsonSerializer<Dictionary<TKey, TValue>>
|
||||||
|
{
|
||||||
|
public Type ValueType => typeof(Dictionary<TKey, TValue>);
|
||||||
|
public Dictionary<TKey, TValue> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
|
||||||
|
{
|
||||||
|
var dictionary = new Dictionary<TKey, TValue>();
|
||||||
|
var reader = context.Reader;
|
||||||
|
|
||||||
|
reader.ReadStartDocument();
|
||||||
|
while (reader.ReadBsonType() != BsonType.EndOfDocument)
|
||||||
|
{
|
||||||
|
var key = (TKey)Convert.ChangeType(reader.ReadName(), typeof(TKey));
|
||||||
|
var value = (TValue)BsonSerializer.Deserialize<TValue>(reader);
|
||||||
|
dictionary[key] = value;
|
||||||
|
}
|
||||||
|
reader.ReadEndDocument();
|
||||||
|
|
||||||
|
return dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, Dictionary<TKey, TValue> value)
|
||||||
|
{
|
||||||
|
var writer = context.Writer;
|
||||||
|
|
||||||
|
writer.WriteStartDocument();
|
||||||
|
foreach (var kvp in value)
|
||||||
|
{
|
||||||
|
writer.WriteName(kvp.Key.ToString());
|
||||||
|
BsonSerializer.Serialize(writer, kvp.Value);
|
||||||
|
}
|
||||||
|
writer.WriteEndDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value)
|
||||||
|
{
|
||||||
|
var writer = context.Writer;
|
||||||
|
|
||||||
|
writer.WriteStartDocument();
|
||||||
|
foreach (var kvp in (Dictionary < TKey, TValue > )value)
|
||||||
|
{
|
||||||
|
writer.WriteName(kvp.Key.ToString());
|
||||||
|
BsonSerializer.Serialize(writer, kvp.Value);
|
||||||
|
}
|
||||||
|
writer.WriteEndDocument();
|
||||||
|
}
|
||||||
|
object IBsonSerializer.Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) =>
|
||||||
|
Deserialize(context, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DatabaseManager
|
||||||
|
{
|
||||||
|
public static Database db;
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
BsonSerializer.RegisterSerializer(typeof(Dictionary<int, ulong>), new CustomDictionarySerializer<int, ulong>());
|
||||||
|
BsonSerializer.RegisterSerializer(typeof(Dictionary<int, List<int>>), new CustomDictionarySerializer<int, List<int>>());
|
||||||
|
RegisterSubclasses<FComponent>();
|
||||||
|
Logger.Print("Connecting to MongoDB...");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
db = new Database(Server.config.mongoDatabase.uri, Server.config.mongoDatabase.collection);
|
||||||
|
Logger.Print("Connected to MongoDB database");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.PrintError(ex.Message);
|
||||||
|
Logger.PrintError("Without initialized database the game server will crash. You can't run this server without MongoDB");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
static void RegisterSubclasses<TBase>()
|
||||||
|
{
|
||||||
|
// Trova tutte le classi che ereditano da TBase
|
||||||
|
var derivedTypes = Assembly.GetExecutingAssembly()
|
||||||
|
.GetTypes()
|
||||||
|
.Where(t => t.IsClass && !t.IsAbstract && typeof(TBase).IsAssignableFrom(t));
|
||||||
|
|
||||||
|
foreach (var type in derivedTypes)
|
||||||
|
{
|
||||||
|
if (!BsonClassMap.IsClassMapRegistered(type))
|
||||||
|
{
|
||||||
|
BsonClassMap.LookupClassMap(type); // Registra automaticamente il mapping BSON
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
96
Campofinale/Game/BitsetManager.cs
Normal file
96
Campofinale/Game/BitsetManager.cs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game
|
||||||
|
{
|
||||||
|
public class BitsetManager
|
||||||
|
{
|
||||||
|
public Player player;
|
||||||
|
public Dictionary<int, List<int>> bitsets = new Dictionary<int, List<int>>();
|
||||||
|
|
||||||
|
|
||||||
|
public BitsetManager(Player player) {
|
||||||
|
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(Dictionary<int, List<int>> savedBitset)
|
||||||
|
{
|
||||||
|
if (savedBitset != null)
|
||||||
|
{
|
||||||
|
bitsets=savedBitset;
|
||||||
|
}
|
||||||
|
InitBitsets();
|
||||||
|
List<ulong> hardcodedLevelHaveBeen = new()
|
||||||
|
{
|
||||||
|
51810140172,
|
||||||
|
531424959210205184,
|
||||||
|
590604267523,
|
||||||
|
17039360
|
||||||
|
};
|
||||||
|
LongBitSet levelHaveBeen=new LongBitSet(hardcodedLevelHaveBeen.ToArray());
|
||||||
|
List<ulong> hardcodedReadActiveBlackbox = new()
|
||||||
|
{
|
||||||
|
1081145935319335202,
|
||||||
|
2267743508524
|
||||||
|
};
|
||||||
|
LongBitSet readActiveBlackbox = new LongBitSet(hardcodedReadActiveBlackbox.ToArray());
|
||||||
|
foreach (int v in levelHaveBeen.ConvertToIntValues())
|
||||||
|
{
|
||||||
|
AddValue(BitsetType.LevelHaveBeen, v);
|
||||||
|
}
|
||||||
|
foreach (int v in readActiveBlackbox.ConvertToIntValues())
|
||||||
|
{
|
||||||
|
AddValue(BitsetType.ReadActiveBlackbox, v);
|
||||||
|
}
|
||||||
|
foreach (int v in strIdNumTable.char_doc_id.dic.Values)
|
||||||
|
{
|
||||||
|
AddValue(BitsetType.CharDoc, v);
|
||||||
|
}
|
||||||
|
foreach (int v in strIdNumTable.char_voice_id.dic.Values)
|
||||||
|
{
|
||||||
|
AddValue(BitsetType.CharVoice, v);
|
||||||
|
}
|
||||||
|
foreach(int v in ResourceManager.strIdNumTable.wiki_id.dic.Values)
|
||||||
|
{
|
||||||
|
AddValue(BitsetType.Wiki, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void InitBitsets()
|
||||||
|
{
|
||||||
|
foreach (BitsetType bitsetType in Enum.GetValues(typeof(BitsetType)))
|
||||||
|
{
|
||||||
|
int id=(int)bitsetType;
|
||||||
|
if (!bitsets.ContainsKey(id))
|
||||||
|
{
|
||||||
|
bitsets.Add(id, new List<int>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void AddValue(BitsetType type, int value)
|
||||||
|
{
|
||||||
|
int id = (int)type;
|
||||||
|
if (!bitsets[id].Contains(value))
|
||||||
|
{
|
||||||
|
bitsets[id].Add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void RemoveValue(BitsetType type, int value)
|
||||||
|
{
|
||||||
|
int id = (int)type;
|
||||||
|
if (bitsets[id].Contains(value))
|
||||||
|
{
|
||||||
|
bitsets[id].Remove(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
479
Campofinale/Game/Character/Character.cs
Normal file
479
Campofinale/Game/Character/Character.cs
Normal file
@ -0,0 +1,479 @@
|
|||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf.Collections;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
using MongoDB.Driver;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static Campofinale.Resource.ResourceManager.CharGrowthTable;
|
||||||
|
using static Campofinale.Resource.ResourceManager.WeaponUpgradeTemplateTable;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Character
|
||||||
|
{
|
||||||
|
public class Character
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
[BsonElement("templateId")]
|
||||||
|
public string id;
|
||||||
|
public ulong guid;
|
||||||
|
public ulong weaponGuid;
|
||||||
|
|
||||||
|
public int level;
|
||||||
|
public int xp;
|
||||||
|
public ulong owner;
|
||||||
|
public double curHp;
|
||||||
|
public float ultimateSp = 200;
|
||||||
|
public uint potential = 0;
|
||||||
|
public string breakNode = "charBreak20";
|
||||||
|
public List<string> passiveSkillNodes = new();
|
||||||
|
public List<string> attrNodes = new();
|
||||||
|
public List<string> factoryNodes = new();
|
||||||
|
public Dictionary<int,ulong> equipCol = new() { { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 } };
|
||||||
|
public Character()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Character(ulong owner, string id) : this(owner, id, 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public Dictionary<AttributeType, (double baseVal, double val)> CalcAttributes()
|
||||||
|
{
|
||||||
|
Dictionary<AttributeType, (double baseVal, double val)> attributes = new();
|
||||||
|
foreach (var item in GetAttributes())
|
||||||
|
{
|
||||||
|
attributes.Add((AttributeType)item.attrType, (item.attrValue, item.attrValue));
|
||||||
|
}
|
||||||
|
Item weapon = GetOwner().inventoryManager.items.Find(w => w.guid == weaponGuid);
|
||||||
|
if(weapon != null)
|
||||||
|
{
|
||||||
|
WeaponBasicTable wTable = ResourceManager.weaponBasicTable[weapon.id];
|
||||||
|
WeaponUpgradeTemplateTable template = ResourceManager.weaponUpgradeTemplateTable[wTable.levelTemplateId];
|
||||||
|
WeaponCurve curve=template.list.Find(c => c.weaponLv == weapon.level);
|
||||||
|
attributes[AttributeType.Atk] = (attributes[AttributeType.Atk].baseVal + curve.baseAtk, attributes[AttributeType.Atk].baseVal + curve.baseAtk);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Won't be very precise but for now
|
||||||
|
foreach (var equip in equipCol)
|
||||||
|
{
|
||||||
|
Item EquipItem = GetOwner().inventoryManager.items.Find(e => e.guid == equip.Value);
|
||||||
|
if (EquipItem != null)
|
||||||
|
{
|
||||||
|
foreach (var modifier in EquipItem.GetEquipAttributeModifier())
|
||||||
|
{
|
||||||
|
switch (modifier.modifierType)
|
||||||
|
{
|
||||||
|
case ModifierType.BaseAddition:
|
||||||
|
case ModifierType.Addition:
|
||||||
|
attributes=SetValueDic(attributes, modifier.attrType, GetValueDic(attributes, modifier.attrType) + modifier.attrValue);
|
||||||
|
break;
|
||||||
|
case ModifierType.Multiplier:
|
||||||
|
case ModifierType.BaseMultiplier:
|
||||||
|
attributes=SetValueDic(attributes, modifier.attrType, GetValueDic(attributes, modifier.attrType) * 1 + modifier.attrValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attributes[AttributeType.MaxHp] = (attributes[AttributeType.MaxHp].baseVal, attributes[AttributeType.MaxHp].val + attributes[AttributeType.Str].val * 10);
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
public double GetValueDic(Dictionary<AttributeType, (double baseVal, double val)> dic, AttributeType type)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (dic.ContainsKey(type))
|
||||||
|
{
|
||||||
|
return dic[type].val;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public Dictionary<AttributeType, (double baseVal, double val)> SetValueDic(Dictionary<AttributeType, (double baseVal, double val)> dic,AttributeType type,double value)
|
||||||
|
{
|
||||||
|
if (dic.ContainsKey(type))
|
||||||
|
{
|
||||||
|
dic[type] = (dic[type].baseVal,value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dic.Add(type, (0, value));
|
||||||
|
}
|
||||||
|
return dic;
|
||||||
|
}
|
||||||
|
public void UnlockNode(string nodeId)
|
||||||
|
{
|
||||||
|
CharTalentNode nodeInfo = ResourceManager.GetTalentNode(id, nodeId);
|
||||||
|
if (nodeInfo == null) return;
|
||||||
|
//TODO remove cost items
|
||||||
|
switch (nodeInfo.nodeType)
|
||||||
|
{
|
||||||
|
case TalentNodeType.CharBreak:
|
||||||
|
breakNode = nodeId;
|
||||||
|
break;
|
||||||
|
case TalentNodeType.EquipBreak:
|
||||||
|
breakNode = nodeId;
|
||||||
|
break;
|
||||||
|
case TalentNodeType.Attr:
|
||||||
|
attrNodes.Add(nodeId);
|
||||||
|
break;
|
||||||
|
case TalentNodeType.PassiveSkill:
|
||||||
|
passiveSkillNodes.Add(nodeId);
|
||||||
|
break;
|
||||||
|
case TalentNodeType.FactorySkill:
|
||||||
|
factoryNodes.Add(nodeId);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Logger.PrintWarn($"Unimplemented NodeType {nodeInfo.nodeType}, not unlocked server side.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
GetOwner().Send(new PacketScCharUnlockTalentNode(GetOwner(), this,nodeId));
|
||||||
|
}
|
||||||
|
public Character(ulong owner,string id, int level) : this()
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.level = level;
|
||||||
|
guid = GetOwner().random.Next();
|
||||||
|
this.weaponGuid = GetOwner().inventoryManager.AddWeapon(ResourceManager.charGrowthTable[id].defaultWeaponId, 1).guid;
|
||||||
|
this.curHp = CalcAttributes()[AttributeType.MaxHp].val;
|
||||||
|
}
|
||||||
|
public int GetSkillMaxLevel()
|
||||||
|
{
|
||||||
|
if (GetBreakStage() == 0)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}else if (GetBreakStage() == 1)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
else if (GetBreakStage() == 2)
|
||||||
|
{
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
else if (GetBreakStage() == 3)
|
||||||
|
{
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
else if (GetBreakStage() == 4)
|
||||||
|
{
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<ResourceManager.Attribute> GetAttributes()
|
||||||
|
{
|
||||||
|
int lev = level - 1 + GetBreakStage();
|
||||||
|
return ResourceManager.characterTable[id].attributes[lev].Attribute.attrs;
|
||||||
|
}
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c=>c.roleId == this.owner);
|
||||||
|
}
|
||||||
|
public SceneCharacter ToSceneProto()
|
||||||
|
{
|
||||||
|
SceneCharacter proto= new SceneCharacter()
|
||||||
|
{
|
||||||
|
Level = level,
|
||||||
|
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
MsgGeneration = 1,
|
||||||
|
|
||||||
|
SkillList =
|
||||||
|
{
|
||||||
|
new ServerSkill()
|
||||||
|
{
|
||||||
|
Blackboard = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
InstId=GetOwner().random.Next(),
|
||||||
|
Level=GetSkillMaxLevel(),
|
||||||
|
Source=BattleSkillSource.Default,
|
||||||
|
PotentialLv=GetSkillMaxLevel(),
|
||||||
|
SkillId=id+"_NormalSkill",
|
||||||
|
},
|
||||||
|
new ServerSkill()
|
||||||
|
{
|
||||||
|
Blackboard = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
InstId=GetOwner().random.Next(),
|
||||||
|
Level=GetSkillMaxLevel(),
|
||||||
|
Source=BattleSkillSource.Default,
|
||||||
|
PotentialLv=GetSkillMaxLevel(),
|
||||||
|
SkillId=id+"_ComboSkill",
|
||||||
|
},
|
||||||
|
new ServerSkill()
|
||||||
|
{
|
||||||
|
Blackboard = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
InstId=GetOwner().random.Next(),
|
||||||
|
Level=GetSkillMaxLevel(),
|
||||||
|
Source=BattleSkillSource.Default,
|
||||||
|
PotentialLv=GetSkillMaxLevel(),
|
||||||
|
SkillId=id+"_UltimateSkill",
|
||||||
|
},
|
||||||
|
new ServerSkill()
|
||||||
|
{
|
||||||
|
Blackboard = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
InstId=GetOwner().random.Next(),
|
||||||
|
Level=GetSkillMaxLevel(),
|
||||||
|
Source=BattleSkillSource.Default,
|
||||||
|
PotentialLv=GetSkillMaxLevel(),
|
||||||
|
SkillId=id+"_NormalAttack",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Name = $"{ResourceManager.characterTable[id].engName}",
|
||||||
|
|
||||||
|
CommonInfo = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
Id = guid,
|
||||||
|
Position = GetOwner().position.ToProto(),
|
||||||
|
Rotation = GetOwner().rotation.ToProto(),
|
||||||
|
SceneNumId = GetOwner().curSceneNumId,
|
||||||
|
Templateid = id,
|
||||||
|
Type = (int)0,
|
||||||
|
|
||||||
|
},
|
||||||
|
Attrs =
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
foreach(var attr in CalcAttributes())
|
||||||
|
{
|
||||||
|
proto.Attrs.Add(new AttrInfo()
|
||||||
|
{
|
||||||
|
AttrType = (int)attr.Key,
|
||||||
|
BasicValue = attr.Value.baseVal,
|
||||||
|
Value = attr.Value.val
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
public int GetBreakStage()
|
||||||
|
{
|
||||||
|
if (ResourceManager.charBreakNodeTable.ContainsKey(breakNode))
|
||||||
|
{
|
||||||
|
int breakStage = ResourceManager.charBreakNodeTable[breakNode].breakStage;
|
||||||
|
return breakStage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public bool IsEquipped(ulong equipGuid)
|
||||||
|
{
|
||||||
|
return equipCol.Values.Contains(equipGuid);
|
||||||
|
}
|
||||||
|
public Dictionary<int,ulong> GetEquipCol()
|
||||||
|
{
|
||||||
|
Dictionary<int, ulong> equips = new();
|
||||||
|
foreach(var item in equipCol)
|
||||||
|
{
|
||||||
|
if (item.Value != 0)
|
||||||
|
{
|
||||||
|
equips.Add(item.Key,item.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return equips;
|
||||||
|
}
|
||||||
|
public CharInfo ToProto()
|
||||||
|
{
|
||||||
|
CharInfo info = new CharInfo()
|
||||||
|
{
|
||||||
|
Exp = xp,
|
||||||
|
Level = level,
|
||||||
|
IsDead = curHp < 1,
|
||||||
|
|
||||||
|
Objid = guid,
|
||||||
|
Templateid = id,
|
||||||
|
CharType = CharType.DefaultType,
|
||||||
|
OwnTime = 1,
|
||||||
|
NormalSkill = id + "_NormalSkill",
|
||||||
|
WeaponId = weaponGuid,
|
||||||
|
PotentialLevel = potential,
|
||||||
|
EquipCol =
|
||||||
|
{
|
||||||
|
GetEquipCol()
|
||||||
|
},
|
||||||
|
|
||||||
|
Talent = new()
|
||||||
|
{
|
||||||
|
LatestBreakNode= breakNode,
|
||||||
|
LatestPassiveSkillNodes =
|
||||||
|
{
|
||||||
|
passiveSkillNodes
|
||||||
|
},
|
||||||
|
AttrNodes =
|
||||||
|
{
|
||||||
|
attrNodes
|
||||||
|
},
|
||||||
|
|
||||||
|
LatestFactorySkillNodes =
|
||||||
|
{
|
||||||
|
factoryNodes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
BattleMgrInfo = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
Ultimatesp= ultimateSp,
|
||||||
|
|
||||||
|
},
|
||||||
|
SkillInfo = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
NormalSkill = id + "_NormalSkill",
|
||||||
|
ComboSkill = id + "_ComboSkill",
|
||||||
|
UltimateSkill = id + "_UltimateSkill",
|
||||||
|
DispNormalAttackSkill = id + "_NormalAttack",
|
||||||
|
|
||||||
|
LevelInfo =
|
||||||
|
{
|
||||||
|
new SkillLevelInfo()
|
||||||
|
{
|
||||||
|
SkillId=id+"_NormalAttack",
|
||||||
|
SkillLevel=GetSkillMaxLevel(),
|
||||||
|
SkillMaxLevel=GetSkillMaxLevel(),
|
||||||
|
SkillEnhancedLevel=GetSkillMaxLevel()
|
||||||
|
},
|
||||||
|
new SkillLevelInfo()
|
||||||
|
{
|
||||||
|
SkillId=id+"_NormalSkill",
|
||||||
|
SkillLevel=GetSkillMaxLevel(),
|
||||||
|
SkillMaxLevel=GetSkillMaxLevel(),
|
||||||
|
SkillEnhancedLevel=GetSkillMaxLevel()
|
||||||
|
},
|
||||||
|
new SkillLevelInfo()
|
||||||
|
{
|
||||||
|
SkillId=id+"_UltimateSkill",
|
||||||
|
SkillLevel=GetSkillMaxLevel(),
|
||||||
|
SkillMaxLevel=GetSkillMaxLevel(),
|
||||||
|
SkillEnhancedLevel=GetSkillMaxLevel()
|
||||||
|
},
|
||||||
|
new SkillLevelInfo()
|
||||||
|
{
|
||||||
|
SkillId=id+"_ComboSkill",
|
||||||
|
SkillLevel=GetSkillMaxLevel(),
|
||||||
|
SkillMaxLevel=GetSkillMaxLevel(),
|
||||||
|
SkillEnhancedLevel=GetSkillMaxLevel()
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Item wep = GetOwner().inventoryManager.items.Find(w => w.guid == weaponGuid);
|
||||||
|
if (wep != null)
|
||||||
|
{
|
||||||
|
//TODO weapon skills
|
||||||
|
}
|
||||||
|
foreach (ulong equipGuid in equipCol.Values)
|
||||||
|
{
|
||||||
|
Item item = GetOwner().inventoryManager.items.Find(i => i.guid == equipGuid);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
string equipSuitId = ResourceManager.GetEquipSuitTableKey(item.id);
|
||||||
|
if (equipSuitId.Length > 0)
|
||||||
|
{
|
||||||
|
if (info.EquipSuit.ContainsKey(equipSuitId))
|
||||||
|
{
|
||||||
|
info.EquipSuit[equipSuitId] += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.EquipSuit.Add(equipSuitId, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
public (int,int,int) CalculateLevelAndGoldCost(int addedXp)
|
||||||
|
{
|
||||||
|
int gold = 0;
|
||||||
|
int curLevel = this.level;
|
||||||
|
while(addedXp >= ResourceManager.charLevelUpTable["" + curLevel].exp)
|
||||||
|
{
|
||||||
|
gold += ResourceManager.charLevelUpTable["" + curLevel].gold;
|
||||||
|
addedXp -= ResourceManager.charLevelUpTable["" + curLevel].exp;
|
||||||
|
curLevel++;
|
||||||
|
if(curLevel >= 80)
|
||||||
|
{
|
||||||
|
curLevel = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (curLevel, gold, addedXp);
|
||||||
|
}
|
||||||
|
public void LevelUp(RepeatedField<ItemInfo> items)
|
||||||
|
{
|
||||||
|
int addedXp = 0;
|
||||||
|
foreach (var item in items)
|
||||||
|
{
|
||||||
|
addedXp += ResourceManager.expItemDataMap[item.ResId].expGain * item.ResCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
(int, int, int) CalculatedValues = CalculateLevelAndGoldCost(xp+addedXp);
|
||||||
|
items.Add(new ItemInfo()
|
||||||
|
{
|
||||||
|
ResId = "item_gold",
|
||||||
|
ResCount = CalculatedValues.Item2
|
||||||
|
});
|
||||||
|
if (GetOwner().inventoryManager.ConsumeItems(items))
|
||||||
|
{
|
||||||
|
this.level = CalculatedValues.Item1;
|
||||||
|
this.xp= CalculatedValues.Item3;
|
||||||
|
ScCharLevelUp levelUp = new()
|
||||||
|
{
|
||||||
|
CharObjID = guid,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
ScCharSyncLevelExp synclevel = new()
|
||||||
|
{
|
||||||
|
Exp = xp,
|
||||||
|
CharObjID = guid,
|
||||||
|
Level = level
|
||||||
|
};
|
||||||
|
GetOwner().Send(ScMsgId.ScCharSyncLevelExp, synclevel);
|
||||||
|
GetOwner().Send(ScMsgId.ScCharLevelUp, levelUp);
|
||||||
|
GetOwner().Send(new PacketScSyncWallet(GetOwner()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Campofinale/Game/Dungeons/Dungeon.cs
Normal file
22
Campofinale/Game/Dungeons/Dungeon.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Dungeons
|
||||||
|
{
|
||||||
|
public class Dungeon
|
||||||
|
{
|
||||||
|
public DungeonTable table;
|
||||||
|
public Vector3f prevPlayerPos;
|
||||||
|
public Vector3f prevPlayerRot;
|
||||||
|
public int prevPlayerSceneNumId;
|
||||||
|
public Player player;
|
||||||
|
public Dungeon()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
Campofinale/Game/Entities/Entity.cs
Normal file
58
Campofinale/Game/Entities/Entity.cs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Entities
|
||||||
|
{
|
||||||
|
public class Entity
|
||||||
|
{
|
||||||
|
public ulong guid;
|
||||||
|
public int level;
|
||||||
|
public ulong worldOwner;
|
||||||
|
public double curHp;
|
||||||
|
public ulong levelLogicId;
|
||||||
|
public ulong belongLevelScriptId;
|
||||||
|
public int dependencyGroupId;
|
||||||
|
public ObjectType type;
|
||||||
|
public Vector3f Position=new();
|
||||||
|
public Vector3f Rotation = new();
|
||||||
|
public Vector3f BornPos=new();
|
||||||
|
public Vector3f BornRot=new();
|
||||||
|
public List<ParamKeyValue> properties=new();
|
||||||
|
public int sceneNumId;
|
||||||
|
public bool spawned = false;
|
||||||
|
public Entity()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public Entity(ulong guid, int level, ulong worldOwner,int scene)
|
||||||
|
{
|
||||||
|
this.guid = guid;
|
||||||
|
this.level = level;
|
||||||
|
this.worldOwner = worldOwner;
|
||||||
|
this.sceneNumId = scene;
|
||||||
|
}
|
||||||
|
public virtual void Damage(double dmg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Heal(double heal)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public virtual bool Interact(string eventName, Google.Protobuf.Collections.MapField<string, DynamicParameter> properties)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c => c.roleId == worldOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
112
Campofinale/Game/Entities/EntityCharacter.cs
Normal file
112
Campofinale/Game/Entities/EntityCharacter.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Entities
|
||||||
|
{
|
||||||
|
public class EntityCharacter : Entity
|
||||||
|
{
|
||||||
|
|
||||||
|
public new double curHp
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetChar().curHp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public new Vector3f Position
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetOwner().position;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
GetOwner().position = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public new Vector3f Rotation
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return GetOwner().rotation;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
GetOwner().rotation = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public EntityCharacter(ulong guid, ulong worldOwner)
|
||||||
|
{
|
||||||
|
this.guid = guid;
|
||||||
|
this.worldOwner = worldOwner;
|
||||||
|
|
||||||
|
}
|
||||||
|
public override void Damage(double dmg)
|
||||||
|
{
|
||||||
|
GetChar().curHp -= dmg;
|
||||||
|
|
||||||
|
ScCharSyncStatus state = new()
|
||||||
|
{
|
||||||
|
IsDead = GetChar().curHp < 1,
|
||||||
|
Objid = guid,
|
||||||
|
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp=curHp,
|
||||||
|
|
||||||
|
Ultimatesp=GetChar().ultimateSp,
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
ScEntityPropertyChange prop = new()
|
||||||
|
{
|
||||||
|
InstId=guid,
|
||||||
|
Info = new()
|
||||||
|
{
|
||||||
|
Hp=curHp,
|
||||||
|
Ultimatesp= GetChar().ultimateSp,
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GetOwner().Send(ScMsgId.ScCharSyncStatus, state);
|
||||||
|
GetOwner().Send(ScMsgId.ScEntityPropertyChange, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Heal(double heal)
|
||||||
|
{
|
||||||
|
GetChar().curHp += heal;
|
||||||
|
|
||||||
|
ScCharSyncStatus state = new()
|
||||||
|
{
|
||||||
|
IsDead = GetChar().curHp < 1,
|
||||||
|
Objid = guid,
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
Ultimatesp = GetChar().ultimateSp,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ScEntityPropertyChange prop = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
Info = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
Ultimatesp = GetChar().ultimateSp,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GetOwner().Send(ScMsgId.ScCharSyncStatus, state);
|
||||||
|
GetOwner().Send(ScMsgId.ScEntityPropertyChange, prop);
|
||||||
|
}
|
||||||
|
public Character.Character GetChar()
|
||||||
|
{
|
||||||
|
return GetOwner().chars.Find(c => c.guid == guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
168
Campofinale/Game/Entities/EntityInteractive.cs
Normal file
168
Campofinale/Game/Entities/EntityInteractive.cs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Entities
|
||||||
|
{
|
||||||
|
public class EntityInteractive : Entity
|
||||||
|
{
|
||||||
|
public string templateId;
|
||||||
|
public Dictionary<InteractiveComponentType, List<ParamKeyValue>> componentProperties = new();
|
||||||
|
public EntityInteractive()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public EntityInteractive(string templateId, ulong worldOwner, Vector3f pos, Vector3f rot, int scene, ulong g=0)
|
||||||
|
{
|
||||||
|
if (g == 0)
|
||||||
|
{
|
||||||
|
this.guid = (ulong)new Random().NextInt64();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.guid = g;
|
||||||
|
}
|
||||||
|
this.level = 1;
|
||||||
|
this.worldOwner = worldOwner;
|
||||||
|
this.Position = pos;
|
||||||
|
this.Rotation = rot;
|
||||||
|
this.BornPos = pos;
|
||||||
|
this.BornRot = rot;
|
||||||
|
this.templateId = templateId;
|
||||||
|
this.sceneNumId = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SceneInteractive ToProto()
|
||||||
|
{
|
||||||
|
|
||||||
|
SceneInteractive proto = new SceneInteractive()
|
||||||
|
{
|
||||||
|
CommonInfo = new()
|
||||||
|
{
|
||||||
|
Hp = 100,
|
||||||
|
|
||||||
|
Id = guid,
|
||||||
|
Templateid = templateId,
|
||||||
|
BelongLevelScriptId = belongLevelScriptId,
|
||||||
|
|
||||||
|
SceneNumId = sceneNumId,
|
||||||
|
Position = Position.ToProto(),
|
||||||
|
Rotation = Rotation.ToProto(),
|
||||||
|
|
||||||
|
Type = (int)5,
|
||||||
|
},
|
||||||
|
|
||||||
|
//Meta =dependencyGroupId,
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
Properties =
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
DynamicParameter p = prop.ToProto();
|
||||||
|
(bool, int) index = GetPropertyIndex(prop.key, proto.Properties.Keys.Count > 0 ? proto.Properties.Keys.Max() : 0);
|
||||||
|
if (p != null && index.Item1)
|
||||||
|
{
|
||||||
|
proto.Properties.Add(index.Item2, p);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
foreach (var comp in componentProperties)
|
||||||
|
{
|
||||||
|
foreach (var prop in comp.Value)
|
||||||
|
{
|
||||||
|
DynamicParameter p = prop.ToProto();
|
||||||
|
(bool, int) index = GetPropertyIndex(prop.key, proto.Properties.Keys.Count > 0 ? proto.Properties.Keys.Max() : 0);
|
||||||
|
if (p != null && index.Item1)
|
||||||
|
{
|
||||||
|
proto.Properties.Add(index.Item2, p);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (bool,int) GetPropertyIndex(string key, int maxCur)
|
||||||
|
{
|
||||||
|
int i= maxCur;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string oriTemplateId = ResourceManager.interactiveTable.interactiveDataDict[templateId].templateId;
|
||||||
|
InteractiveData data=ResourceManager.interactiveData.Find(i=>i.id == oriTemplateId);
|
||||||
|
if(data != null)
|
||||||
|
{
|
||||||
|
return (true,data.propertyKeyToIdMap[key]);
|
||||||
|
}
|
||||||
|
return (false, maxCur + 1);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//Logger.PrintError(ex.Message);
|
||||||
|
return (false,maxCur+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public override void Damage(double dmg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public override bool Interact(string eventName, Google.Protobuf.Collections.MapField<string, DynamicParameter> props)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (eventName == "open_chest")
|
||||||
|
{
|
||||||
|
ScSceneUpdateInteractiveProperty update = new()
|
||||||
|
{
|
||||||
|
Id = guid,
|
||||||
|
SceneNumId = GetOwner().curSceneNumId,
|
||||||
|
Properties =
|
||||||
|
{
|
||||||
|
{4, new DynamicParameter()
|
||||||
|
{
|
||||||
|
RealType=3,
|
||||||
|
ValueType=3,
|
||||||
|
ValueIntList={1}
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GetOwner().Send(ScMsgId.ScSceneUpdateInteractiveProperty, update);
|
||||||
|
GetOwner().inventoryManager.AddRewards(properties.Find(p=>p.key== "reward_id").value.valueArray[0].valueString,Position,1);
|
||||||
|
GetOwner().sceneManager.KillEntity(guid,true,1);
|
||||||
|
GetOwner().noSpawnAnymore.Add(guid);
|
||||||
|
GetOwner().sceneManager.GetScene(sceneNumId).AddCollection("int_trchest_common", 1);
|
||||||
|
GetOwner().Send(new PacketScSceneCollectionSync(GetOwner()));
|
||||||
|
return true;
|
||||||
|
}else if(eventName == "pick_inst")
|
||||||
|
{
|
||||||
|
//TODO
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public override void Heal(double heal)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
125
Campofinale/Game/Entities/EntityMonster.cs
Normal file
125
Campofinale/Game/Entities/EntityMonster.cs
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Entities
|
||||||
|
{
|
||||||
|
public class EntityMonster : Entity
|
||||||
|
{
|
||||||
|
public string templateId;
|
||||||
|
public EntityMonster()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public EntityMonster(string templateId, int level, ulong worldOwner, Vector3f pos, Vector3f rot, int scene, ulong g=0)
|
||||||
|
{
|
||||||
|
if (g == 0)
|
||||||
|
{
|
||||||
|
this.guid = (ulong)new Random().NextInt64();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.guid = g;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.level = level;
|
||||||
|
this.worldOwner = worldOwner;
|
||||||
|
this.Position = pos;
|
||||||
|
this.Rotation = rot;
|
||||||
|
this.BornPos = pos;
|
||||||
|
this.BornRot = rot;
|
||||||
|
this.templateId = templateId;
|
||||||
|
this.curHp = GetAttribValue(AttributeType.MaxHp);
|
||||||
|
this.sceneNumId=scene;
|
||||||
|
}
|
||||||
|
public double GetAttribValue(AttributeType type)
|
||||||
|
{
|
||||||
|
return GetAttributes().Find(a => a.AttrType == (int)type).Value;
|
||||||
|
}
|
||||||
|
public List<AttrInfo> GetAttributes()
|
||||||
|
{
|
||||||
|
List<AttrInfo> attrInfo = new();
|
||||||
|
EnemyTable table = ResourceManager.enemyTable[templateId];
|
||||||
|
enemyAttributeTemplateTable[table.attrTemplateId].levelDependentAttributes[level].attrs.ForEach(attr =>
|
||||||
|
{
|
||||||
|
attrInfo.Add(new AttrInfo()
|
||||||
|
{
|
||||||
|
AttrType = attr.attrType,
|
||||||
|
BasicValue = attr.attrValue,
|
||||||
|
Value = attr.attrValue
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
enemyAttributeTemplateTable[table.attrTemplateId].levelIndependentAttributes.attrs.ForEach(attr =>
|
||||||
|
{
|
||||||
|
attrInfo.Add(new AttrInfo()
|
||||||
|
{
|
||||||
|
AttrType = attr.attrType,
|
||||||
|
BasicValue = attr.attrValue,
|
||||||
|
Value = attr.attrValue
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return attrInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SceneMonster ToProto()
|
||||||
|
{
|
||||||
|
SceneMonster proto = new SceneMonster()
|
||||||
|
{
|
||||||
|
Level = level,
|
||||||
|
CommonInfo = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
Id = guid,
|
||||||
|
Templateid = templateId,
|
||||||
|
BelongLevelScriptId = belongLevelScriptId,
|
||||||
|
SceneNumId = sceneNumId,
|
||||||
|
Position = Position.ToProto(),
|
||||||
|
Rotation = Rotation.ToProto(),
|
||||||
|
|
||||||
|
Type =(int) ObjectTypeIndex.Enemy,
|
||||||
|
},
|
||||||
|
Attrs =
|
||||||
|
{
|
||||||
|
GetAttributes()
|
||||||
|
},
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
public override void Damage(double dmg)
|
||||||
|
{
|
||||||
|
curHp -= dmg;
|
||||||
|
ScEntityPropertyChange prop = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
Info = new()
|
||||||
|
{
|
||||||
|
Hp = curHp,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GetOwner().Send(ScMsgId.ScEntityPropertyChange, prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Heal(double heal)
|
||||||
|
{
|
||||||
|
curHp += heal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
66
Campofinale/Game/Entities/EntityNpc.cs
Normal file
66
Campofinale/Game/Entities/EntityNpc.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Entities
|
||||||
|
{
|
||||||
|
public class EntityNpc : Entity
|
||||||
|
{
|
||||||
|
public string templateId;
|
||||||
|
public EntityNpc()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public EntityNpc(string templateId, ulong worldOwner, Vector3f pos, Vector3f rot,int scene,ulong guid)
|
||||||
|
{
|
||||||
|
this.guid = (ulong)guid;
|
||||||
|
this.level = 1;
|
||||||
|
this.worldOwner = worldOwner;
|
||||||
|
this.Position = pos;
|
||||||
|
this.Rotation = rot;
|
||||||
|
this.BornPos = pos;
|
||||||
|
this.BornRot = rot;
|
||||||
|
this.templateId = templateId;
|
||||||
|
this.sceneNumId = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public SceneNpc ToProto()
|
||||||
|
{
|
||||||
|
SceneNpc proto = new SceneNpc()
|
||||||
|
{
|
||||||
|
CommonInfo = new()
|
||||||
|
{
|
||||||
|
Hp = 100,
|
||||||
|
Id = guid,
|
||||||
|
Templateid = templateId,
|
||||||
|
BelongLevelScriptId=belongLevelScriptId,
|
||||||
|
|
||||||
|
SceneNumId =sceneNumId,
|
||||||
|
Position = Position.ToProto(),
|
||||||
|
Rotation = Rotation.ToProto(),
|
||||||
|
|
||||||
|
Type = (int)type,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
public override void Damage(double dmg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Heal(double heal)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
26
Campofinale/Game/Factory/Components/FComponentBusLoader.cs
Normal file
26
Campofinale/Game/Factory/Components/FComponentBusLoader.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentBusLoader : FComponent
|
||||||
|
{
|
||||||
|
public string lastPutinItemId = "";
|
||||||
|
public FComponentBusLoader(uint id) : base(id, FCComponentType.BusLoader)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.BusLoader = new()
|
||||||
|
{
|
||||||
|
LastPutinItemId= lastPutinItemId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
53
Campofinale/Game/Factory/Components/FComponentPortManager.cs
Normal file
53
Campofinale/Game/Factory/Components/FComponentPortManager.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentPortManager : FComponent
|
||||||
|
{
|
||||||
|
public class FPort
|
||||||
|
{
|
||||||
|
public int index = 0;
|
||||||
|
public uint ownerComId;
|
||||||
|
public uint touchComId;
|
||||||
|
|
||||||
|
public ScdFacComSubPort ToProto()
|
||||||
|
{
|
||||||
|
return new ScdFacComSubPort()
|
||||||
|
{
|
||||||
|
InBlock = false,
|
||||||
|
Index = index,
|
||||||
|
OwnerComId = ownerComId,
|
||||||
|
TouchComId = touchComId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<FPort> ports = new();
|
||||||
|
public FComponentPortManager(uint id, uint mainId) : base(id, FCComponentType.PortManager)
|
||||||
|
{
|
||||||
|
for(int i=0; i < 14; i++)
|
||||||
|
{
|
||||||
|
ports.Add(new FPort()
|
||||||
|
{
|
||||||
|
index = i,
|
||||||
|
ownerComId = mainId,
|
||||||
|
touchComId = 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.PortManager = new();
|
||||||
|
foreach(FPort port in ports)
|
||||||
|
{
|
||||||
|
proto.PortManager.Ports.Add(port.ToProto());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Campofinale/Game/Factory/Components/FComponentPowerPole.cs
Normal file
22
Campofinale/Game/Factory/Components/FComponentPowerPole.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentPowerPole : FComponent
|
||||||
|
{
|
||||||
|
public FComponentPowerPole(uint id) : base(id, FCComponentType.PowerPole)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.PowerPole = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
Campofinale/Game/Factory/Components/FComponentPowerSave.cs
Normal file
25
Campofinale/Game/Factory/Components/FComponentPowerSave.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentPowerSave : FComponent
|
||||||
|
{
|
||||||
|
public FComponentPowerSave(uint id) : base(id, FCComponentType.PowerSave)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.PowerSave = new()
|
||||||
|
{
|
||||||
|
PowerSave=100000
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Campofinale/Game/Factory/Components/FComponentSelector.cs
Normal file
26
Campofinale/Game/Factory/Components/FComponentSelector.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentSelector : FComponent
|
||||||
|
{
|
||||||
|
public string selectedItemId = "";
|
||||||
|
public FComponentSelector(uint id) : base(id, FCComponentType.Selector)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.Selector = new()
|
||||||
|
{
|
||||||
|
SelectedItemId= selectedItemId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
Campofinale/Game/Factory/Components/FComponentStablePower.cs
Normal file
25
Campofinale/Game/Factory/Components/FComponentStablePower.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentStablePower : FComponent
|
||||||
|
{
|
||||||
|
public FComponentStablePower(uint id) : base(id, FCComponentType.StablePower)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.StablePower = new()
|
||||||
|
{
|
||||||
|
PowerGenPerSec=150
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Campofinale/Game/Factory/Components/FComponentSubHub.cs
Normal file
26
Campofinale/Game/Factory/Components/FComponentSubHub.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentSubHub : FComponent
|
||||||
|
{
|
||||||
|
public int level = 1;
|
||||||
|
public FComponentSubHub(uint id) : base(id, FCComponentType.SubHub)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.SubHub = new()
|
||||||
|
{
|
||||||
|
Level = level,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
Campofinale/Game/Factory/Components/FComponentTravelPole.cs
Normal file
22
Campofinale/Game/Factory/Components/FComponentTravelPole.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Factory.FactoryNode;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory.Components
|
||||||
|
{
|
||||||
|
public class FComponentTravelPole : FComponent
|
||||||
|
{
|
||||||
|
public FComponentTravelPole(uint id) : base(id, FCComponentType.TravelPole)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
proto.TravelPole = new();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
459
Campofinale/Game/Factory/FactoryManager.cs
Normal file
459
Campofinale/Game/Factory/FactoryManager.cs
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
using Campofinale.Game.Factory.Components;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Factory
|
||||||
|
{
|
||||||
|
public class FactoryManager
|
||||||
|
{
|
||||||
|
public Player player;
|
||||||
|
public List<FactoryChapter> chapters = new();
|
||||||
|
|
||||||
|
|
||||||
|
public FactoryManager(Player player)
|
||||||
|
{
|
||||||
|
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
//TODO Save
|
||||||
|
chapters.Add(new FactoryChapter("domain_1", player.roleId));
|
||||||
|
chapters.Add(new FactoryChapter("domain_2", player.roleId));
|
||||||
|
}
|
||||||
|
public void ExecOp(CsFactoryOp op, ulong seq)
|
||||||
|
{
|
||||||
|
FactoryChapter chapter = GetChapter(op.ChapterId);
|
||||||
|
if (chapter != null)
|
||||||
|
{
|
||||||
|
chapter.ExecOp(op, seq);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScFactoryOpRet ret = new()
|
||||||
|
{
|
||||||
|
RetCode = FactoryOpRetCode.Fail,
|
||||||
|
|
||||||
|
};
|
||||||
|
player.Send(ScMsgId.ScFactoryOpRet, ret, seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
foreach (FactoryChapter chapter in chapters)
|
||||||
|
{
|
||||||
|
chapter.Update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public FactoryChapter GetChapter(string id)
|
||||||
|
{
|
||||||
|
return chapters.Find(c=>c.chapterId==id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FactoryChapter
|
||||||
|
{
|
||||||
|
public string chapterId;
|
||||||
|
public ulong ownerId;
|
||||||
|
public List<FactoryNode> nodes=new();
|
||||||
|
public uint v = 1;
|
||||||
|
public uint compV = 0;
|
||||||
|
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (FactoryNode node in nodes)
|
||||||
|
{
|
||||||
|
node.Update(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public List<FactoryNode> GetNodesInRange(Vector3f pos,float range)
|
||||||
|
{
|
||||||
|
return nodes.FindAll(n => n.position.Distance(pos) <= range);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExecOp(CsFactoryOp op, ulong seq)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (op.OpType)
|
||||||
|
{
|
||||||
|
case FactoryOpType.Place:
|
||||||
|
CreateNode(op.Place, seq);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public uint nextCompV()
|
||||||
|
{
|
||||||
|
compV++;
|
||||||
|
return compV;
|
||||||
|
}
|
||||||
|
private void CreateNode(CsdFactoryOpPlace place, ulong seq)
|
||||||
|
{
|
||||||
|
v++;
|
||||||
|
uint nodeId = v;
|
||||||
|
FactoryBuildingTable table = ResourceManager.factoryBuildingTable[place.TemplateId];
|
||||||
|
FactoryNode node = new()
|
||||||
|
{
|
||||||
|
nodeId = nodeId,
|
||||||
|
templateId = place.TemplateId,
|
||||||
|
mapId = place.MapId,
|
||||||
|
nodeType = table.GetNodeType(),
|
||||||
|
position = new Vector3f(place.Position),
|
||||||
|
direction = new Vector3f(place.Direction),
|
||||||
|
guid = GetOwner().random.NextRand()
|
||||||
|
};
|
||||||
|
|
||||||
|
node.InitComponents(this);
|
||||||
|
nodes.Add(node);
|
||||||
|
ScFactoryModifyChapterNodes edit = new()
|
||||||
|
{
|
||||||
|
ChapterId = chapterId,
|
||||||
|
Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(),
|
||||||
|
|
||||||
|
};
|
||||||
|
GetOwner().Send(new PacketScFactorySyncChapter(GetOwner(), chapterId));
|
||||||
|
edit.Nodes.Add(node.ToProto());
|
||||||
|
Logger.Print(Newtonsoft.Json.JsonConvert.SerializeObject(edit, Newtonsoft.Json.Formatting.Indented));
|
||||||
|
GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, edit);
|
||||||
|
GetOwner().Send(new PacketScFactoryOpRet(GetOwner(), node.nodeId,FactoryOpType.Place),seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FactoryChapter(string chapterId,ulong ownerId)
|
||||||
|
{
|
||||||
|
this.ownerId = ownerId;
|
||||||
|
this.chapterId = chapterId;
|
||||||
|
FactoryNode node = new()
|
||||||
|
{
|
||||||
|
nodeId = v,
|
||||||
|
templateId= "__inventory__",
|
||||||
|
nodeType=FCNodeType.Inventory,
|
||||||
|
mapId=0,
|
||||||
|
deactive=true,
|
||||||
|
guid = GetOwner().random.NextRand()
|
||||||
|
};
|
||||||
|
node.InitComponents(this);
|
||||||
|
nodes.Add(node);
|
||||||
|
}
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c => c.roleId == ownerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FactoryNode
|
||||||
|
{
|
||||||
|
public uint nodeId;
|
||||||
|
public FCNodeType nodeType;
|
||||||
|
public string templateId;
|
||||||
|
public Vector3f position=new();
|
||||||
|
public Vector3f direction = new();
|
||||||
|
public string instKey="";
|
||||||
|
public bool deactive = false;
|
||||||
|
public int mapId;
|
||||||
|
public bool forcePowerOn = false;
|
||||||
|
public List<FComponent> components = new();
|
||||||
|
[BsonIgnore]
|
||||||
|
public bool powered = false;
|
||||||
|
[BsonIgnore]
|
||||||
|
public uint connectedPowerNode = 0;
|
||||||
|
public ulong guid;
|
||||||
|
public void Update(FactoryChapter chapter)
|
||||||
|
{
|
||||||
|
if(!templateId.Contains("hub"))
|
||||||
|
if (GetComponent<FComponentPowerPole>() != null)
|
||||||
|
{
|
||||||
|
FactoryNode curEnergyNode = chapter.nodes.Find(n => n.nodeId == connectedPowerNode && n.position.Distance(position) <= 20 && n.InPower());
|
||||||
|
if (templateId != "power_pole_2")
|
||||||
|
{
|
||||||
|
FactoryNode energyNode = chapter.GetNodesInRange(position, 20).Find(n=>n.GetComponent< FComponentPowerPole>()!=null && n.InPower());
|
||||||
|
if (energyNode != null && curEnergyNode==null && energyNode.connectedPowerNode!=nodeId)
|
||||||
|
{
|
||||||
|
powered= true;
|
||||||
|
connectedPowerNode = energyNode.nodeId;
|
||||||
|
chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, new ScFactoryModifyChapterNodes() { Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Nodes = { this.ToProto()} });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (curEnergyNode == null && powered==true)
|
||||||
|
{
|
||||||
|
powered = false;
|
||||||
|
connectedPowerNode = 0;
|
||||||
|
chapter.GetOwner().Send(ScMsgId.ScFactoryModifyChapterNodes, new ScFactoryModifyChapterNodes() { Tms = DateTime.UtcNow.ToUnixTimestampMilliseconds(), Nodes = { this.ToProto() } });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Check near
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool InPower()
|
||||||
|
{
|
||||||
|
if (forcePowerOn)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return powered;
|
||||||
|
}
|
||||||
|
public FComponent GetComponent<FComponent>() where FComponent : class
|
||||||
|
{
|
||||||
|
return components.Find(c => c is FComponent) as FComponent;
|
||||||
|
}
|
||||||
|
public FMesh GetMesh()
|
||||||
|
{
|
||||||
|
FMesh mesh = new FMesh();
|
||||||
|
|
||||||
|
if (ResourceManager.factoryBuildingTable.ContainsKey(templateId))
|
||||||
|
{
|
||||||
|
FactoryBuildingTable table = ResourceManager.factoryBuildingTable[templateId];
|
||||||
|
|
||||||
|
double centerX = position.x + table.range.width / 2.0;
|
||||||
|
double centerZ = position.z + table.range.depth / 2.0;
|
||||||
|
|
||||||
|
Vector3f p1 = new Vector3f(position.x, position.y, position.z);
|
||||||
|
Vector3f p2 = new Vector3f(
|
||||||
|
position.x + table.range.width,
|
||||||
|
position.y + table.range.height,
|
||||||
|
position.z + table.range.depth
|
||||||
|
);
|
||||||
|
|
||||||
|
p1 = RotateAroundY(p1, new Vector3f((float)centerX, position.y, (float)centerZ), direction.y);
|
||||||
|
p2 = RotateAroundY(p2, new Vector3f((float)centerX, position.y, (float)centerZ), direction.y);
|
||||||
|
mesh.points.Add(p1);
|
||||||
|
mesh.points.Add(p2);
|
||||||
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
private Vector3f RotateAroundY(Vector3f point, Vector3f origin, double angleDegrees)
|
||||||
|
{
|
||||||
|
double angleRadians = angleDegrees * (Math.PI / 180.0);
|
||||||
|
double cosTheta = Math.Cos(angleRadians);
|
||||||
|
double sinTheta = Math.Sin(angleRadians);
|
||||||
|
|
||||||
|
double dx = point.x - origin.x;
|
||||||
|
double dz = point.z - origin.z;
|
||||||
|
|
||||||
|
double rotatedX = origin.x + (dx * cosTheta - dz * sinTheta);
|
||||||
|
double rotatedZ = origin.z + (dx * sinTheta + dz * cosTheta);
|
||||||
|
|
||||||
|
return new Vector3f((float)rotatedX, point.y, (float)rotatedZ);
|
||||||
|
}
|
||||||
|
public ScdFacNode ToProto()
|
||||||
|
{
|
||||||
|
ScdFacNode node = new ScdFacNode()
|
||||||
|
{
|
||||||
|
InstKey = instKey,
|
||||||
|
NodeId=nodeId,
|
||||||
|
TemplateId=templateId,
|
||||||
|
StableId= GetStableId(),
|
||||||
|
IsDeactive= deactive,
|
||||||
|
Power = new()
|
||||||
|
{
|
||||||
|
InPower= InPower(),
|
||||||
|
NeedInPower=false,
|
||||||
|
},
|
||||||
|
|
||||||
|
NodeType=(int)nodeType,
|
||||||
|
Transform = new()
|
||||||
|
{
|
||||||
|
Position = position.ToProtoScd(),
|
||||||
|
Direction=direction.ToProtoScd(),
|
||||||
|
MapId=mapId,
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if(templateId!="__inventory__")
|
||||||
|
{
|
||||||
|
node.Transform.Mesh = GetMesh().ToProto();
|
||||||
|
node.Transform.WorldPosition = position.ToProto();
|
||||||
|
node.Transform.WorldRotation = direction.ToProto();
|
||||||
|
node.InteractiveObject = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
node.Flag = 0;
|
||||||
|
node.InstKey = "";
|
||||||
|
}
|
||||||
|
foreach(FComponent comp in components)
|
||||||
|
{
|
||||||
|
node.Components.Add(comp.ToProto());
|
||||||
|
node.ComponentPos.Add((int)comp.GetComPos(), comp.compId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
public uint GetStableId()
|
||||||
|
{
|
||||||
|
return 10000+nodeId;
|
||||||
|
}
|
||||||
|
public FCComponentType GetMainCompType()
|
||||||
|
{
|
||||||
|
string nodeTypeName = nodeType.ToString();
|
||||||
|
if (Enum.TryParse(nodeTypeName, out FCComponentType fromName))
|
||||||
|
{
|
||||||
|
return fromName;
|
||||||
|
}
|
||||||
|
return FCComponentType.Invalid;
|
||||||
|
}
|
||||||
|
public void InitComponents(FactoryChapter chapter)
|
||||||
|
{
|
||||||
|
switch (nodeType)
|
||||||
|
{
|
||||||
|
case FCNodeType.PowerPole:
|
||||||
|
components.Add(new FComponentPowerPole(chapter.nextCompV()).Init());
|
||||||
|
break;
|
||||||
|
case FCNodeType.PowerDiffuser:
|
||||||
|
components.Add(new FComponentPowerPole(chapter.nextCompV()).Init());
|
||||||
|
break;
|
||||||
|
case FCNodeType.TravelPole:
|
||||||
|
components.Add(new FComponentTravelPole(chapter.nextCompV()).Init());
|
||||||
|
break;
|
||||||
|
case FCNodeType.Hub:
|
||||||
|
components.Add(new FComponentSelector(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPowerPole(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPowerSave(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentStablePower(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentBusLoader(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPortManager(chapter.nextCompV(),GetComponent<FComponentBusLoader>().compId).Init());
|
||||||
|
forcePowerOn = true;
|
||||||
|
break;
|
||||||
|
case FCNodeType.SubHub:
|
||||||
|
components.Add(new FComponentSubHub(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentSelector(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPowerPole(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPowerSave(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentStablePower(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentBusLoader(chapter.nextCompV()).Init());
|
||||||
|
components.Add(new FComponentPortManager(chapter.nextCompV(), GetComponent<FComponentBusLoader>().compId).Init());
|
||||||
|
forcePowerOn = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
components.Add(new FComponent(chapter.nextCompV(), GetMainCompType()).Init());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
[BsonDiscriminator(Required = true)]
|
||||||
|
[BsonKnownTypes(typeof(FComponentSelector))]
|
||||||
|
|
||||||
|
public class FComponent
|
||||||
|
{
|
||||||
|
public class FCompInventory
|
||||||
|
{
|
||||||
|
public ScdFacComInventory ToProto()
|
||||||
|
{
|
||||||
|
return new ScdFacComInventory()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public uint compId;
|
||||||
|
public FCComponentType type;
|
||||||
|
public FCompInventory inventory;
|
||||||
|
|
||||||
|
public FComponent(uint id, FCComponentType t)
|
||||||
|
{
|
||||||
|
this.compId = id;
|
||||||
|
this.type = t;
|
||||||
|
}
|
||||||
|
public FCComponentPos GetComPos()
|
||||||
|
{
|
||||||
|
|
||||||
|
string compTypeName = type.ToString();
|
||||||
|
if (Enum.TryParse(compTypeName, out FCComponentPos fromName))
|
||||||
|
{
|
||||||
|
return fromName;
|
||||||
|
}
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case FCComponentType.PowerPole:
|
||||||
|
return FCComponentPos.PowerPole;
|
||||||
|
}
|
||||||
|
return FCComponentPos.Invalid;
|
||||||
|
}
|
||||||
|
public ScdFacCom ToProto()
|
||||||
|
{
|
||||||
|
ScdFacCom proto = new ScdFacCom()
|
||||||
|
{
|
||||||
|
ComponentType = (int)type,
|
||||||
|
ComponentId = compId,
|
||||||
|
|
||||||
|
};
|
||||||
|
SetComponentInfo(proto);
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void SetComponentInfo(ScdFacCom proto)
|
||||||
|
{
|
||||||
|
if (inventory != null)
|
||||||
|
{
|
||||||
|
proto.Inventory = inventory.ToProto();
|
||||||
|
}
|
||||||
|
else if (type == FCComponentType.PowerPole)
|
||||||
|
{
|
||||||
|
proto.PowerPole = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual FComponent Init()
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case FCComponentType.Inventory:
|
||||||
|
inventory = new();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class FMesh
|
||||||
|
{
|
||||||
|
public FCMeshType type;
|
||||||
|
public List<Vector3f> points=new();
|
||||||
|
public ScdFacMesh ToProto()
|
||||||
|
{
|
||||||
|
ScdFacMesh m = new ScdFacMesh()
|
||||||
|
{
|
||||||
|
MeshType = (int)type
|
||||||
|
};
|
||||||
|
foreach (Vector3f p in points)
|
||||||
|
{
|
||||||
|
m.Points.Add(new ScdVec3Int()
|
||||||
|
{
|
||||||
|
X = (int)p.x,
|
||||||
|
Y = (int)p.y,
|
||||||
|
Z = (int)p.z
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
262
Campofinale/Game/Gacha/GachaManager.cs
Normal file
262
Campofinale/Game/Gacha/GachaManager.cs
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Gacha
|
||||||
|
{
|
||||||
|
public class GachaManager
|
||||||
|
{
|
||||||
|
|
||||||
|
public Player player;
|
||||||
|
internal ulong upSeqId;
|
||||||
|
const double fiftyfifty = 0.45; // 50% (make it less than real 50, because the randomness make win fifty fifty every time
|
||||||
|
|
||||||
|
private static readonly Random random = new Random();
|
||||||
|
public GachaManager(Player player)
|
||||||
|
{
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public (int fiveStarPity, int sixStarPity, GachaTransaction? lastSixStar, bool isFiftyFiftyLost) GetCurrentPity(string templateId)
|
||||||
|
{
|
||||||
|
List<GachaTransaction> transactionList = DatabaseManager.db.LoadGachaTransaction(player.roleId, templateId);
|
||||||
|
transactionList = transactionList.OrderBy(g => g.transactionTime).ToList();
|
||||||
|
|
||||||
|
int fiveStarPity = 0;
|
||||||
|
int sixStarPity = 0;
|
||||||
|
|
||||||
|
GachaTransaction? lastSixStar = null;
|
||||||
|
foreach (var transaction in transactionList)
|
||||||
|
{
|
||||||
|
if (transaction.rarity == 5)
|
||||||
|
{
|
||||||
|
fiveStarPity = 0;
|
||||||
|
sixStarPity++;
|
||||||
|
}
|
||||||
|
else if (transaction.rarity == 6)
|
||||||
|
{
|
||||||
|
fiveStarPity = 0;
|
||||||
|
sixStarPity = 0;
|
||||||
|
lastSixStar = transaction;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fiveStarPity++;
|
||||||
|
sixStarPity++;
|
||||||
|
}
|
||||||
|
//Logger.Print("Current calculated: " + sixStarPity);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFiftyFiftyLost = false;
|
||||||
|
if (lastSixStar != null)
|
||||||
|
{
|
||||||
|
isFiftyFiftyLost = lastSixStar.itemId != templateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (fiveStarPity, sixStarPity, lastSixStar, isFiftyFiftyLost);
|
||||||
|
}
|
||||||
|
public void DoGacha(string gachaId,int attempts)
|
||||||
|
{
|
||||||
|
const double prob6Star = 0.008; // 0.8%
|
||||||
|
const double prob5Star = 0.08; // 8%
|
||||||
|
|
||||||
|
(int fiveStarPity, int sixStarPity, GachaTransaction? lastSixStar, bool isFiftyFiftyLost)
|
||||||
|
PityInfo = GetCurrentPity(gachaId);
|
||||||
|
int increaseTime = 0;
|
||||||
|
int pityforcalculate = PityInfo.sixStarPity-64;
|
||||||
|
if(pityforcalculate < 1)
|
||||||
|
{
|
||||||
|
pityforcalculate = 0;
|
||||||
|
}
|
||||||
|
GachaCharPoolTable table = ResourceManager.gachaCharPoolTable[gachaId];
|
||||||
|
GachaCharPoolContentTable content = ResourceManager.gachaCharPoolContentTable[gachaId];
|
||||||
|
GachaCharPoolTypeTable type = ResourceManager.gachaCharPoolTypeTable[""+table.type];
|
||||||
|
//Sanity check
|
||||||
|
if (table==null || content == null || type==null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<GachaCharPoolItem> fiveStars = content.list.FindAll(c => c.starLevel == 5);
|
||||||
|
List<GachaCharPoolItem> sixStars = content.list.FindAll(c => c.starLevel == 6);
|
||||||
|
List<GachaCharPoolItem> fourStars = content.list.FindAll(c => c.starLevel == 4);
|
||||||
|
List<GachaTransaction> transactions = new();
|
||||||
|
for (int i = 0; i < attempts; i++)
|
||||||
|
{
|
||||||
|
double roll = random.NextDouble();
|
||||||
|
double fifty = random.NextDouble();
|
||||||
|
double finalProb6Star = prob6Star + 0.05f * pityforcalculate;
|
||||||
|
PityInfo.fiveStarPity++;
|
||||||
|
PityInfo.sixStarPity++;
|
||||||
|
GachaTransaction transaction = null;
|
||||||
|
//Six star pull
|
||||||
|
if (roll < finalProb6Star || PityInfo.sixStarPity>=type.softGuarantee)
|
||||||
|
{
|
||||||
|
PityInfo.sixStarPity -= PityInfo.sixStarPity >= type.softGuarantee ? type.softGuarantee : PityInfo.sixStarPity;
|
||||||
|
if (table.upCharIds.Count > 0)
|
||||||
|
{
|
||||||
|
transaction = GetChar(table.upCharIds[0], PityInfo.isFiftyFiftyLost, fifty, sixStars, 6);
|
||||||
|
|
||||||
|
if (transaction.itemId != table.upCharIds[0])
|
||||||
|
{
|
||||||
|
PityInfo.isFiftyFiftyLost = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PityInfo.isFiftyFiftyLost = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transaction = GetChar("", PityInfo.isFiftyFiftyLost, fifty, sixStars, 6);
|
||||||
|
}
|
||||||
|
pityforcalculate = 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (roll < prob5Star || PityInfo.fiveStarPity >= 10)
|
||||||
|
{
|
||||||
|
|
||||||
|
PityInfo.fiveStarPity -= PityInfo.fiveStarPity >= 10 ? 10 : PityInfo.fiveStarPity;
|
||||||
|
|
||||||
|
if (table.upCharIds.Count > 1)
|
||||||
|
{
|
||||||
|
transaction = GetChar(table.upCharIds[1], false, fifty, fiveStars, 5);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transaction = GetChar("", false, fifty, fiveStars, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transaction = GetChar("", false, fifty, fourStars, 4);
|
||||||
|
}
|
||||||
|
if(PityInfo.sixStarPity > 65)
|
||||||
|
{
|
||||||
|
pityforcalculate++;
|
||||||
|
}
|
||||||
|
transactions.Add(transaction);
|
||||||
|
}
|
||||||
|
ScGachaSyncPullResult result = new ScGachaSyncPullResult()
|
||||||
|
{
|
||||||
|
GachaPoolId = gachaId,
|
||||||
|
GachaType =table.type,
|
||||||
|
|
||||||
|
OriResultIds =
|
||||||
|
{
|
||||||
|
},
|
||||||
|
Star5GotCount = transactions.FindAll(t => t.rarity == 5).Count,
|
||||||
|
Star6GotCount = transactions.FindAll(t => t.rarity == 6).Count,
|
||||||
|
FinalResults =
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
UpGotCount = transactions.FindAll(t => table.upCharIds.Contains(t.itemId)).Count,
|
||||||
|
|
||||||
|
};
|
||||||
|
foreach (GachaTransaction transaction in transactions)
|
||||||
|
{
|
||||||
|
transaction.gachaTemplateId = gachaId;
|
||||||
|
bool exist = player.chars.Find(c => c.id == transaction.itemId) != null;
|
||||||
|
result.OriResultIds.Add(transaction.itemId);
|
||||||
|
result.FinalResults.Add(new ScdGachaFinalResult()
|
||||||
|
{
|
||||||
|
IsNew = !exist,
|
||||||
|
ItemId = !exist ? transaction.itemId : "item_charpotentialup_" + transaction.itemId,
|
||||||
|
RewardItemId= !exist ? transaction.itemId : "item_charpotentialup_"+ transaction.itemId,
|
||||||
|
RewardIds =
|
||||||
|
{
|
||||||
|
$"reward_{transaction.rarity}starChar_weaponCoin",
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
DatabaseManager.db.AddGachaTransaction(transaction);
|
||||||
|
}
|
||||||
|
player.Send(ScMsgId.ScGachaSyncPullResult, result,upSeqId);
|
||||||
|
ScGachaModifyPoolRoleData roleData = new()
|
||||||
|
{
|
||||||
|
GachaPoolId = gachaId,
|
||||||
|
GachaType = table.type,
|
||||||
|
GachaPoolCategoryRoleData = new()
|
||||||
|
{
|
||||||
|
GachaPoolType = table.type,
|
||||||
|
Star5SoftGuaranteeProgress = PityInfo.fiveStarPity,
|
||||||
|
SoftGuaranteeProgress = PityInfo.sixStarPity,
|
||||||
|
TotalPullCount = PityInfo.sixStarPity
|
||||||
|
},
|
||||||
|
GachaPoolRoleData = new()
|
||||||
|
{
|
||||||
|
GachaPoolId = gachaId,
|
||||||
|
HardGuaranteeProgress = PityInfo.sixStarPity,
|
||||||
|
SoftGuaranteeProgress = PityInfo.sixStarPity,
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
player.Send(ScMsgId.ScGachaModifyPoolRoleData, roleData, upSeqId);
|
||||||
|
}
|
||||||
|
public GachaTransaction GetChar(string upChar,bool guaranteed, double fifty, List<GachaCharPoolItem> items, int rarity)
|
||||||
|
{
|
||||||
|
GachaTransaction transaction = new()
|
||||||
|
{
|
||||||
|
transactionTime = DateTime.UtcNow.Ticks,
|
||||||
|
ownerId = player.roleId,
|
||||||
|
rarity = rarity,
|
||||||
|
};
|
||||||
|
if((fifty >= fiftyfifty || guaranteed) && rarity != 4 && upChar.Length >0)
|
||||||
|
{
|
||||||
|
transaction.itemId = upChar;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = random.Next(0,items.Count); // Miglior randomizzazione
|
||||||
|
// index = (int)((1 - Math.Pow(random.NextDouble(), 2)) * (items.Count - 1));
|
||||||
|
|
||||||
|
// Se vuoi evitare di prendere spesso i primi 2-3 elementi:
|
||||||
|
// index = (int)Math.Pow(random.NextDouble(), 1.5) * items.Count;
|
||||||
|
if (index > items.Count-1)
|
||||||
|
{
|
||||||
|
index = items.Count-1;
|
||||||
|
}
|
||||||
|
if(index < 0)
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
transaction.itemId = items[index].charId;
|
||||||
|
transaction.hasLost = transaction.itemId != upChar;
|
||||||
|
}
|
||||||
|
return transaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GachaHistoryAPI GetGachaHistoryPage(PlayerData data, string banner, int p = 1)
|
||||||
|
{
|
||||||
|
GachaHistoryAPI api = new();
|
||||||
|
int pageSize = 5;
|
||||||
|
|
||||||
|
List<GachaTransaction> transactionList = DatabaseManager.db.LoadGachaTransaction(data.roleId, banner);
|
||||||
|
transactionList = transactionList.OrderByDescending(g => g.transactionTime).ToList();
|
||||||
|
int maxPages=(int)Math.Ceiling((double)transactionList.Count / pageSize);
|
||||||
|
api.maxPages = maxPages;
|
||||||
|
api.curPage = p;
|
||||||
|
api.transactionList= transactionList.Skip((p - 1) * pageSize).Take(pageSize).ToList();
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
public class GachaHistoryAPI
|
||||||
|
{
|
||||||
|
public int maxPages = 0;
|
||||||
|
public int curPage = 0;
|
||||||
|
public List<GachaTransaction> transactionList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
Campofinale/Game/Gacha/GachaTransaction.cs
Normal file
23
Campofinale/Game/Gacha/GachaTransaction.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Gacha
|
||||||
|
{
|
||||||
|
public class GachaTransaction
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
public ulong ownerId;
|
||||||
|
public long transactionTime;
|
||||||
|
public string itemId;
|
||||||
|
public string gachaTemplateId;
|
||||||
|
public int rarity;
|
||||||
|
public bool hasLost = false;
|
||||||
|
}
|
||||||
|
}
|
16
Campofinale/Game/GameConstants.cs
Normal file
16
Campofinale/Game/GameConstants.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Game
|
||||||
|
{
|
||||||
|
public static class GameConstants
|
||||||
|
{
|
||||||
|
public static string GAME_VERSION = "0.5.28"; //CBT 2
|
||||||
|
public static string GAME_VERSION_ASSET_URL = "https://beyond.hg-cdn.com/uXUuLlNbIYmMMTlN/0.5/update/6/1/Windows/0.5.28_U1mgxrslUitdn3hb/files";//CBT 2
|
||||||
|
public static int MAX_TEAMS_NUMBER = 5; //Not used yet
|
||||||
|
public static (long, string) SERVER_UID = (99, "99"); //Not used yet, no friend chat in current Beta
|
||||||
|
}
|
||||||
|
}
|
223
Campofinale/Game/Inventory/InventoryManager.cs
Normal file
223
Campofinale/Game/Inventory/InventoryManager.cs
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf.Collections;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Inventory
|
||||||
|
{
|
||||||
|
public class InventoryManager
|
||||||
|
{
|
||||||
|
public Player owner;
|
||||||
|
public List<Item> items= new List<Item>();
|
||||||
|
|
||||||
|
public int item_diamond_amt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (items.Find(i => i.id == "item_diamond") == null) return 0;
|
||||||
|
return items.Find(i => i.id == "item_diamond")!.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public int item_gold_amt
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (items.Find(i => i.id == "item_gold") == null) return 0;
|
||||||
|
return items.Find(i => i.id == "item_gold")!.amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item GetItemById(string id)
|
||||||
|
{
|
||||||
|
return items.Find(i => i.id == id);
|
||||||
|
}
|
||||||
|
public InventoryManager(Player o) {
|
||||||
|
|
||||||
|
owner = o;
|
||||||
|
|
||||||
|
}
|
||||||
|
public void AddRewards(string rewardTemplateId, Vector3f pos, int sourceType=1)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ScRewardToastBegin begin = new ScRewardToastBegin()
|
||||||
|
{
|
||||||
|
RewardSourceType = sourceType,
|
||||||
|
RewardToastInstId = owner.random.NextRand(),
|
||||||
|
|
||||||
|
};
|
||||||
|
ScRewardToSceneBegin begin2 = new ScRewardToSceneBegin()
|
||||||
|
{
|
||||||
|
RewardSourceType = sourceType,
|
||||||
|
SourceTemplateId = rewardTemplateId,
|
||||||
|
};
|
||||||
|
ScRewardToastEnd end = new()
|
||||||
|
{
|
||||||
|
RewardToastInstId = begin.RewardToastInstId,
|
||||||
|
|
||||||
|
};
|
||||||
|
List<RewardTable.ItemBundle> bundles = rewardTable[rewardTemplateId].itemBundles;
|
||||||
|
foreach(RewardTable.ItemBundle bundle in bundles)
|
||||||
|
{
|
||||||
|
Item item = new Item()
|
||||||
|
{
|
||||||
|
id=bundle.id
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!item.InstanceType())
|
||||||
|
{
|
||||||
|
item = AddItem(bundle.id, bundle.count);
|
||||||
|
end.RewardVirtualList.Add(new RewardItem()
|
||||||
|
{
|
||||||
|
Count = bundle.count,
|
||||||
|
Id = bundle.id,
|
||||||
|
Inst=item.ToProto().Inst,
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
owner.sceneManager.CreateDrop(pos, bundle);
|
||||||
|
//TODO drops
|
||||||
|
}
|
||||||
|
}
|
||||||
|
owner.Send(Protocol.ScMsgId.ScRewardToastBegin, begin);
|
||||||
|
owner.Send(Protocol.ScMsgId.ScRewardToSceneBegin, begin2);
|
||||||
|
|
||||||
|
|
||||||
|
owner.Send(Protocol.ScMsgId.ScRewardToastEnd, end);
|
||||||
|
owner.Send(Protocol.ScMsgId.ScRewardToSceneEnd, new ScRewardToSceneEnd());
|
||||||
|
owner.Send(new PacketScSyncWallet(owner));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public Item AddWeapon(string id, ulong level)
|
||||||
|
{
|
||||||
|
Item item = new Item(owner.roleId, id, level);
|
||||||
|
items.Add(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
foreach (Item item in items)
|
||||||
|
{
|
||||||
|
DatabaseManager.db.UpsertItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
items = DatabaseManager.db.LoadInventoryItems(owner.roleId);
|
||||||
|
}
|
||||||
|
public Item AddItem(string id, int amt)
|
||||||
|
{
|
||||||
|
Item it = new()
|
||||||
|
{
|
||||||
|
id = id,
|
||||||
|
};
|
||||||
|
if(!it.InstanceType())
|
||||||
|
{
|
||||||
|
|
||||||
|
Item item = items.Find(i=>i.id == id);
|
||||||
|
if (item != null)
|
||||||
|
{
|
||||||
|
// Logger.Print(id + ": " + amt+" added to existing");
|
||||||
|
item.amount += amt;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Logger.Print(id + ": " + amt + " added to new");
|
||||||
|
item = new Item(owner.roleId, id, amt);
|
||||||
|
items.Add(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Logger.Print(id + ": " + amt + " added to new as instance");
|
||||||
|
Item item = new Item(owner.roleId, id, amt);
|
||||||
|
items.Add(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void RemoveItem(Item item,int amt)
|
||||||
|
{
|
||||||
|
item.amount -= amt;
|
||||||
|
if(item.amount <= 0)
|
||||||
|
{
|
||||||
|
items.Remove(item);
|
||||||
|
DatabaseManager.db.DeleteItem(item);
|
||||||
|
}
|
||||||
|
this.owner.Send(new PacketScItemBagScopeModify(this.owner, item));
|
||||||
|
}
|
||||||
|
public bool ConsumeItems(MapField<string, ulong> costItemId2Count)
|
||||||
|
{
|
||||||
|
RepeatedField<ItemInfo> items = new RepeatedField<ItemInfo>();
|
||||||
|
foreach (var item in costItemId2Count)
|
||||||
|
{
|
||||||
|
items.Add(new ItemInfo()
|
||||||
|
{
|
||||||
|
ResCount=(int)item.Value,
|
||||||
|
ResId=item.Key,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return ConsumeItems(items);
|
||||||
|
}
|
||||||
|
public bool ConsumeItems(RepeatedField<ItemInfo> items)
|
||||||
|
{
|
||||||
|
bool found = true;
|
||||||
|
foreach (ItemInfo item in items)
|
||||||
|
{
|
||||||
|
Item i= GetItemById(item.ResId);
|
||||||
|
if (i != null)
|
||||||
|
{
|
||||||
|
if(i.amount < item.ResCount)
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
found = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (ItemInfo item in items)
|
||||||
|
{
|
||||||
|
Item i = GetItemById(item.ResId);
|
||||||
|
if (i != null)
|
||||||
|
{
|
||||||
|
if (i.amount >= item.ResCount)
|
||||||
|
{
|
||||||
|
RemoveItem(i,item.ResCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<uint, int> GetInventoryChapter(string chapterId)
|
||||||
|
{
|
||||||
|
Dictionary<uint, int> dir= new Dictionary<uint, int>();
|
||||||
|
List<Item> citems = items.FindAll(i=>!i.InstanceType());
|
||||||
|
foreach (Item item in citems)
|
||||||
|
{
|
||||||
|
dir.Add((uint)ResourceManager.strIdNumTable.item_id.dic[item.id], item.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
259
Campofinale/Game/Inventory/Item.cs
Normal file
259
Campofinale/Game/Inventory/Item.cs
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using Google.Protobuf.Collections;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Inventory
|
||||||
|
{
|
||||||
|
public class Item
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
[BsonElement("templateId")]
|
||||||
|
public string id;
|
||||||
|
public ulong guid;
|
||||||
|
public int amount = 1;
|
||||||
|
public ulong owner;
|
||||||
|
public ulong level = 1;
|
||||||
|
public ulong xp;
|
||||||
|
public bool locked = false;
|
||||||
|
public ulong attachGemId;
|
||||||
|
public ulong breakthroughLv;
|
||||||
|
public ulong refineLv;
|
||||||
|
public Item() {
|
||||||
|
|
||||||
|
}
|
||||||
|
public Item(ulong owner, string id, int amt)
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.amount = amt;
|
||||||
|
this.level = GetDefaultLevel();
|
||||||
|
guid = GetOwner().random.Next();
|
||||||
|
}
|
||||||
|
public Item(ulong owner, string id, ulong level)
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.amount = 1;
|
||||||
|
this.level = level;
|
||||||
|
guid = GetOwner().random.Next();
|
||||||
|
}
|
||||||
|
public ulong GetDefaultLevel()
|
||||||
|
{
|
||||||
|
switch (ItemType)
|
||||||
|
{
|
||||||
|
case ItemValuableDepotType.Weapon:
|
||||||
|
return 1;
|
||||||
|
case ItemValuableDepotType.Equip:
|
||||||
|
return equipTable[id].minWearLv;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<AttributeModifier> GetEquipAttributeModifier()
|
||||||
|
{
|
||||||
|
List<AttributeModifier> modifiers = ResourceManager.equipTable[id].attrModifiers;
|
||||||
|
|
||||||
|
return modifiers;
|
||||||
|
}
|
||||||
|
public ItemValuableDepotType ItemType
|
||||||
|
{
|
||||||
|
get{
|
||||||
|
return ResourceManager.GetItemTable(id).valuableTabType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public virtual ScdItemGrid ToProto()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (ItemType)
|
||||||
|
{
|
||||||
|
case ItemValuableDepotType.WeaponGem:
|
||||||
|
return new ScdItemGrid()
|
||||||
|
{
|
||||||
|
Count = 1,
|
||||||
|
Id = id,
|
||||||
|
|
||||||
|
Inst = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
Gem = new()
|
||||||
|
{
|
||||||
|
GemId = guid,
|
||||||
|
TemplateId= ResourceManager.GetItemTemplateId(id),
|
||||||
|
WeaponId= GetOwner().inventoryManager.items.Find(i=>i.attachGemId==guid)!=null ? GetOwner().inventoryManager.items.Find(i => i.attachGemId == guid).guid: 0,
|
||||||
|
|
||||||
|
},
|
||||||
|
IsLock = locked
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case ItemValuableDepotType.Weapon:
|
||||||
|
return new ScdItemGrid()
|
||||||
|
{
|
||||||
|
Count = 1,
|
||||||
|
Id = id,
|
||||||
|
|
||||||
|
Inst = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
Weapon = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
EquipCharId = GetOwner().chars.Find(c => c.weaponGuid == guid) != null ? GetOwner().chars.Find(c => c.weaponGuid == guid).guid : 0,
|
||||||
|
WeaponLv = level,
|
||||||
|
TemplateId = ResourceManager.GetItemTemplateId(id),
|
||||||
|
Exp = xp,
|
||||||
|
AttachGemId = attachGemId,
|
||||||
|
|
||||||
|
BreakthroughLv = breakthroughLv,
|
||||||
|
RefineLv = refineLv
|
||||||
|
},
|
||||||
|
|
||||||
|
IsLock = locked
|
||||||
|
}
|
||||||
|
};
|
||||||
|
case ItemValuableDepotType.Equip:
|
||||||
|
ScdItemGrid equip=new ScdItemGrid()
|
||||||
|
{
|
||||||
|
Count = 1,
|
||||||
|
Id = id,
|
||||||
|
|
||||||
|
Inst = new()
|
||||||
|
{
|
||||||
|
InstId = guid,
|
||||||
|
|
||||||
|
Equip = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
EquipCharId = GetOwner().chars.Find(c => c.IsEquipped(guid)) != null ? GetOwner().chars.Find(c => c.IsEquipped(guid)).guid : 0,
|
||||||
|
Equipid = guid,
|
||||||
|
Templateid = ResourceManager.GetItemTemplateId(id),
|
||||||
|
|
||||||
|
},
|
||||||
|
IsLock = locked
|
||||||
|
}
|
||||||
|
};
|
||||||
|
foreach (var item in GetEquipAttributeModifier())
|
||||||
|
{
|
||||||
|
equip.Inst.Equip.Attrs.Add(new EquipAttr()
|
||||||
|
{
|
||||||
|
AttrType= (int)item.attrType,
|
||||||
|
ModifierType=(int)item.modifierType,
|
||||||
|
ModifierValue=item.attrValue,
|
||||||
|
ModifyAttributeType=item.modifyAttributeType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return equip;
|
||||||
|
default:
|
||||||
|
return new ScdItemGrid()
|
||||||
|
{
|
||||||
|
Count = amount,
|
||||||
|
Id = id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
return new ScdItemGrid()
|
||||||
|
{
|
||||||
|
Count = amount,
|
||||||
|
Id = id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c => c.roleId == this.owner);
|
||||||
|
}
|
||||||
|
public (ulong, ulong, ulong) CalculateLevelAndGoldCost(ulong addedXp)
|
||||||
|
{
|
||||||
|
ulong gold = 0;
|
||||||
|
ulong curLevel = this.level;
|
||||||
|
WeaponBasicTable table = ResourceManager.weaponBasicTable[id];
|
||||||
|
WeaponUpgradeTemplateTable upgradeTable = ResourceManager.weaponUpgradeTemplateTable[table.levelTemplateId];
|
||||||
|
while (addedXp >= upgradeTable.list.Find(c=>c.weaponLv==curLevel).lvUpExp)
|
||||||
|
{
|
||||||
|
gold += upgradeTable.list.Find(c => c.weaponLv == curLevel).lvUpGold;
|
||||||
|
addedXp -= upgradeTable.list.Find(c => c.weaponLv == curLevel).lvUpExp;
|
||||||
|
curLevel++;
|
||||||
|
if (curLevel >= 80)
|
||||||
|
{
|
||||||
|
curLevel = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (curLevel, gold, addedXp);
|
||||||
|
}
|
||||||
|
public ulong GetMaterialExp(string id)
|
||||||
|
{
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case "item_weapon_expcard_low":
|
||||||
|
return 200;
|
||||||
|
case "item_weapon_expcard_mid":
|
||||||
|
return 1000;
|
||||||
|
case "item_weapon_expcard_high":
|
||||||
|
return 10000;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void LevelUp(MapField<string, ulong> costItemId2Count, RepeatedField<ulong> costWeaponIds)
|
||||||
|
{
|
||||||
|
//TODO add exp from costWeapons
|
||||||
|
ulong addedXp = 0;
|
||||||
|
foreach (var material in costItemId2Count)
|
||||||
|
{
|
||||||
|
addedXp += GetMaterialExp(material.Key) * material.Value;
|
||||||
|
}
|
||||||
|
(ulong, ulong, ulong) CalculatedValues = CalculateLevelAndGoldCost(xp + addedXp);
|
||||||
|
|
||||||
|
costItemId2Count.Add("item_gold",CalculatedValues.Item2);
|
||||||
|
if (GetOwner().inventoryManager.ConsumeItems(costItemId2Count))
|
||||||
|
{
|
||||||
|
this.level = CalculatedValues.Item1;
|
||||||
|
this.xp = CalculatedValues.Item3;
|
||||||
|
ScWeaponAddExp levelUp = new()
|
||||||
|
{
|
||||||
|
Weaponid = guid,
|
||||||
|
WeaponLv=level,
|
||||||
|
NewExp=xp,
|
||||||
|
|
||||||
|
};
|
||||||
|
GetOwner().Send(ScMsgId.ScWeaponAddExp, levelUp);
|
||||||
|
GetOwner().Send(new PacketScSyncWallet(GetOwner()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool InstanceType()
|
||||||
|
{
|
||||||
|
switch (ItemType)
|
||||||
|
{
|
||||||
|
case ItemValuableDepotType.Weapon:
|
||||||
|
return true;
|
||||||
|
case ItemValuableDepotType.WeaponGem:
|
||||||
|
return true;
|
||||||
|
case ItemValuableDepotType.Equip:
|
||||||
|
return true;
|
||||||
|
case ItemValuableDepotType.SpecialItem:
|
||||||
|
return false;
|
||||||
|
case ItemValuableDepotType.MissionItem:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
64
Campofinale/Game/Mail.cs
Normal file
64
Campofinale/Game/Mail.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
|
||||||
|
namespace Campofinale.Game
|
||||||
|
{
|
||||||
|
public class Mail
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
public ulong owner;
|
||||||
|
public long sendTime = 0;
|
||||||
|
public long expireTime = 0;
|
||||||
|
public ulong guid = 0;
|
||||||
|
public bool isStar = false;
|
||||||
|
public bool claimed = false;
|
||||||
|
public bool isRead = false;
|
||||||
|
public MailType mailType;
|
||||||
|
public MailSubType mailSubType;
|
||||||
|
public Mail_Content content;
|
||||||
|
//todo add rewards
|
||||||
|
public Mail() { }
|
||||||
|
|
||||||
|
|
||||||
|
public CsMailDef ToProto()
|
||||||
|
{
|
||||||
|
return new CsMailDef()
|
||||||
|
{
|
||||||
|
ExpireTime = expireTime,
|
||||||
|
MailId=guid,
|
||||||
|
IsAttachmentGot=claimed,
|
||||||
|
IsRead=isRead,
|
||||||
|
IsStar=isStar,
|
||||||
|
MailType=(int)mailType,
|
||||||
|
MailSubType=(int)mailSubType,
|
||||||
|
SendTime=sendTime,
|
||||||
|
MailContent = new()
|
||||||
|
{
|
||||||
|
Content=content.content,
|
||||||
|
SenderName=content.senderName,
|
||||||
|
Title=content.title,
|
||||||
|
TemplateId=content.templateId,
|
||||||
|
SenderIcon= "Mail/mail_endfield"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Mail_Content
|
||||||
|
{
|
||||||
|
public string templateId = "";
|
||||||
|
public string title = "";
|
||||||
|
public string content = "";
|
||||||
|
public string senderName = "";
|
||||||
|
|
||||||
|
public Mail_Content() { }
|
||||||
|
}
|
||||||
|
}
|
404
Campofinale/Game/SceneManager.cs
Normal file
404
Campofinale/Game/SceneManager.cs
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
using Campofinale.Game.Entities;
|
||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using SharpCompress.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static Campofinale.Resource.ResourceManager.LevelScene.LevelData;
|
||||||
|
|
||||||
|
namespace Campofinale.Game
|
||||||
|
{
|
||||||
|
public class SceneManager
|
||||||
|
{
|
||||||
|
public List<Scene> scenes = new List<Scene>();
|
||||||
|
public Player player;
|
||||||
|
public List<Entity> globalEntities = new List<Entity>();
|
||||||
|
public SceneManager(Player player) {
|
||||||
|
|
||||||
|
this.player = player;
|
||||||
|
|
||||||
|
}
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
if (GetCurScene()!=null)
|
||||||
|
GetCurScene().UpdateShowEntities();
|
||||||
|
}
|
||||||
|
public Entity GetEntity(ulong guid)
|
||||||
|
{
|
||||||
|
Scene scene = scenes.Find(s => s.sceneNumId == player.curSceneNumId);
|
||||||
|
Entity en = globalEntities.Find(e => e.guid == guid);
|
||||||
|
if (en != null)
|
||||||
|
{
|
||||||
|
return en;
|
||||||
|
}
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
return scene.entities.Find(e => e.guid == guid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public void LoadCurrentTeamEntities()
|
||||||
|
{
|
||||||
|
globalEntities.RemoveAll(e => e is EntityCharacter);
|
||||||
|
foreach (Character.Character chara in player.GetCurTeam())
|
||||||
|
{
|
||||||
|
EntityCharacter ch = new(chara.guid, player.roleId);
|
||||||
|
globalEntities.Add(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void LoadCurrent()
|
||||||
|
{
|
||||||
|
Scene curscene = GetCurScene();
|
||||||
|
string sceneConfigPath = curscene.info().defaultState.exportedSceneConfigPath;
|
||||||
|
foreach(Scene scene in scenes.FindAll(s => s.info().defaultState.exportedSceneConfigPath == sceneConfigPath))
|
||||||
|
{
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
scene.Load();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public Scene GetScene(int sceneId)
|
||||||
|
{
|
||||||
|
return scenes.Find(s=>s.sceneNumId==sceneId);
|
||||||
|
}
|
||||||
|
public Scene GetCurScene()
|
||||||
|
{
|
||||||
|
return scenes.Find(s => s.sceneNumId == player.curSceneNumId);
|
||||||
|
}
|
||||||
|
public void SpawnEntity(Entity entity)
|
||||||
|
{
|
||||||
|
|
||||||
|
Scene scene = GetCurScene();
|
||||||
|
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
scene.entities.Add(entity);
|
||||||
|
//Spawn packet
|
||||||
|
player.Send(new PacketScObjectEnterView(player,new List<Entity>{ entity }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void KillEntity(ulong guid, bool killClient=false, int reason=1)
|
||||||
|
{
|
||||||
|
Scene scene = GetCurScene();
|
||||||
|
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
if(GetEntity(guid) is EntityMonster)
|
||||||
|
{
|
||||||
|
EntityMonster monster = (EntityMonster)GetEntity(guid);
|
||||||
|
CreateDrop(monster.Position, new RewardTable.ItemBundle()
|
||||||
|
{
|
||||||
|
id = "item_gem_rarity_3",
|
||||||
|
count=1
|
||||||
|
});
|
||||||
|
LevelScene lv_scene = ResourceManager.GetLevelData(GetEntity(guid).sceneNumId);
|
||||||
|
LevelEnemyData d = lv_scene.levelData.enemies.Find(l => l.levelLogicId == monster.guid);
|
||||||
|
if (d != null)
|
||||||
|
{
|
||||||
|
if (!d.respawnable)
|
||||||
|
{
|
||||||
|
player.noSpawnAnymore.Add(monster.guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (killClient)
|
||||||
|
{
|
||||||
|
ScSceneDestroyEntity destroy = new()
|
||||||
|
{
|
||||||
|
Id = guid,
|
||||||
|
Reason = reason,
|
||||||
|
SceneNumId = GetEntity(guid).sceneNumId,
|
||||||
|
};
|
||||||
|
player.Send(Protocol.ScMsgId.ScSceneDestroyEntity, destroy);
|
||||||
|
}
|
||||||
|
if (GetEntity(guid) != null)
|
||||||
|
{
|
||||||
|
if(scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId) != null)
|
||||||
|
{
|
||||||
|
scenes.Find(s => s.sceneNumId == GetEntity(guid).sceneNumId).entities.Remove(GetEntity(guid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void CreateDrop(Vector3f pos,ResourceManager.RewardTable.ItemBundle bundle)
|
||||||
|
{
|
||||||
|
ItemTable info = ResourceManager.itemTable[bundle.id];
|
||||||
|
Item item = new Item(player.roleId, info.id, bundle.count);
|
||||||
|
EntityInteractive drop = new(info.modelKey, player.roleId, pos, new Vector3f(), GetCurScene().sceneNumId)
|
||||||
|
{
|
||||||
|
type = (ObjectType)5,
|
||||||
|
curHp = 100,
|
||||||
|
properties =
|
||||||
|
{
|
||||||
|
new ParamKeyValue()
|
||||||
|
{
|
||||||
|
key="is_collected",
|
||||||
|
value = new()
|
||||||
|
{
|
||||||
|
type=ParamRealType.Bool,
|
||||||
|
valueArray=new ParamKeyValue.ParamValueAtom[1]
|
||||||
|
{
|
||||||
|
new ParamKeyValue.ParamValueAtom()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new ParamKeyValue()
|
||||||
|
{
|
||||||
|
key="item_id",
|
||||||
|
value = new()
|
||||||
|
{
|
||||||
|
type=ParamRealType.String,
|
||||||
|
valueArray=new ParamKeyValue.ParamValueAtom[1]
|
||||||
|
{
|
||||||
|
new ParamKeyValue.ParamValueAtom()
|
||||||
|
{
|
||||||
|
|
||||||
|
valueString=info.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
drop.properties.Add(new ParamKeyValue()
|
||||||
|
{
|
||||||
|
key = "count",
|
||||||
|
value = new()
|
||||||
|
{
|
||||||
|
type = ParamRealType.Int,
|
||||||
|
|
||||||
|
valueArray = new ParamKeyValue.ParamValueAtom[1]
|
||||||
|
{
|
||||||
|
new ParamKeyValue.ParamValueAtom()
|
||||||
|
{
|
||||||
|
valueBit64=bundle.count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (item.InstanceType())
|
||||||
|
{
|
||||||
|
drop.properties.Add(new ParamKeyValue()
|
||||||
|
{
|
||||||
|
key = "item_inst",
|
||||||
|
value = new()
|
||||||
|
{
|
||||||
|
type = ParamRealType.String,
|
||||||
|
valueArray = new ParamKeyValue.ParamValueAtom[1]
|
||||||
|
{
|
||||||
|
new ParamKeyValue.ParamValueAtom()
|
||||||
|
{
|
||||||
|
valueString=Newtonsoft.Json.JsonConvert.SerializeObject(item.ToProto().Inst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
SpawnEntity(drop);
|
||||||
|
}
|
||||||
|
public ulong GetSceneGuid(int sceneNumId)
|
||||||
|
{
|
||||||
|
return scenes.Find(s=>s.sceneNumId == sceneNumId).guid;
|
||||||
|
}
|
||||||
|
//TODO Save and get
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
foreach (var level in ResourceManager.levelDatas)
|
||||||
|
{
|
||||||
|
if(scenes.Find(s=>s.sceneNumId==level.idNum) == null)
|
||||||
|
scenes.Add(new Scene()
|
||||||
|
{
|
||||||
|
guid = (ulong)player.random.Next(),
|
||||||
|
ownerId=player.roleId,
|
||||||
|
sceneNumId=level.idNum,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnloadAllByConfigPath(string sceneConfigPath)
|
||||||
|
{
|
||||||
|
foreach (Scene scene in scenes.FindAll(s => s.info().defaultState.exportedSceneConfigPath == sceneConfigPath))
|
||||||
|
{
|
||||||
|
if (scene != null)
|
||||||
|
{
|
||||||
|
scene.alreadyLoaded = false;
|
||||||
|
scene.Unload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Scene
|
||||||
|
{
|
||||||
|
public ulong ownerId;
|
||||||
|
public ulong guid;
|
||||||
|
public int sceneNumId;
|
||||||
|
public Dictionary<string, int> collections = new();
|
||||||
|
[BsonIgnore,JsonIgnore]
|
||||||
|
public List<Entity> entities = new();
|
||||||
|
[BsonIgnore, JsonIgnore]
|
||||||
|
public bool alreadyLoaded = false;
|
||||||
|
public int GetCollection(string id)
|
||||||
|
{
|
||||||
|
if (collections.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return collections[id];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCollection(string id,int amt)
|
||||||
|
{
|
||||||
|
if (collections.ContainsKey(id))
|
||||||
|
{
|
||||||
|
collections[id] += amt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
collections.Add(id, amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<Entity> GetEntityExcludingChar()
|
||||||
|
{
|
||||||
|
return entities.FindAll(c => c is not EntityCharacter);
|
||||||
|
}
|
||||||
|
public void Unload()
|
||||||
|
{
|
||||||
|
List<ulong> guids = new();
|
||||||
|
foreach(Entity e in entities)
|
||||||
|
{
|
||||||
|
guids.Add(e.guid);
|
||||||
|
}
|
||||||
|
entities.Clear();
|
||||||
|
GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), guids));
|
||||||
|
}
|
||||||
|
public LevelScene info()
|
||||||
|
{
|
||||||
|
return levelDatas.Find(l => l.idNum == sceneNumId);
|
||||||
|
}
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
if (info().isSeamless && alreadyLoaded) return;
|
||||||
|
alreadyLoaded = true;
|
||||||
|
Unload();
|
||||||
|
LevelScene lv_scene = ResourceManager.GetLevelData(sceneNumId);
|
||||||
|
|
||||||
|
lv_scene.levelData.interactives.ForEach(en =>
|
||||||
|
{
|
||||||
|
if (en.defaultHide || GetOwner().noSpawnAnymore.Contains(en.levelLogicId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EntityInteractive entity = new(en.entityDataIdKey, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId)
|
||||||
|
{
|
||||||
|
belongLevelScriptId=en.belongLevelScriptId,
|
||||||
|
dependencyGroupId=en.dependencyGroupId,
|
||||||
|
levelLogicId= en.levelLogicId,
|
||||||
|
type = en.entityType,
|
||||||
|
properties= en.properties,
|
||||||
|
componentProperties=en.componentProperties,
|
||||||
|
};
|
||||||
|
entities.Add(entity);
|
||||||
|
});
|
||||||
|
lv_scene.levelData.factoryRegions.ForEach(en =>
|
||||||
|
{
|
||||||
|
if (en.defaultHide || GetOwner().noSpawnAnymore.Contains(en.levelLogicId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EntityInteractive entity = new(en.entityDataIdKey, ownerId, en.position, en.rotation, sceneNumId, en.levelLogicId)
|
||||||
|
{
|
||||||
|
belongLevelScriptId = en.belongLevelScriptId,
|
||||||
|
dependencyGroupId = 0,
|
||||||
|
levelLogicId = en.levelLogicId,
|
||||||
|
type = en.entityType,
|
||||||
|
};
|
||||||
|
entities.Add(entity);
|
||||||
|
});
|
||||||
|
lv_scene.levelData.enemies.ForEach(en =>
|
||||||
|
{
|
||||||
|
if(en.defaultHide || GetOwner().noSpawnAnymore.Contains(en.levelLogicId)) return;
|
||||||
|
EntityMonster entity = new(en.entityDataIdKey,en.level,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
|
||||||
|
{
|
||||||
|
type=en.entityType,
|
||||||
|
belongLevelScriptId=en.belongLevelScriptId,
|
||||||
|
levelLogicId = en.levelLogicId
|
||||||
|
};
|
||||||
|
entities.Add(entity);
|
||||||
|
});
|
||||||
|
lv_scene.levelData.npcs.ForEach(en =>
|
||||||
|
{
|
||||||
|
if (en.defaultHide) return;
|
||||||
|
if (en.npcGroupId.Contains("chr")) return;
|
||||||
|
EntityNpc entity = new(en.entityDataIdKey,ownerId,en.position,en.rotation, sceneNumId, en.levelLogicId)
|
||||||
|
{
|
||||||
|
belongLevelScriptId = en.belongLevelScriptId,
|
||||||
|
levelLogicId = en.levelLogicId,
|
||||||
|
type = en.entityType,
|
||||||
|
|
||||||
|
};
|
||||||
|
entities.Add(entity);
|
||||||
|
});
|
||||||
|
/*GetEntityExcludingChar().ForEach(e =>
|
||||||
|
{
|
||||||
|
GetOwner().Send(new PacketScObjectEnterView(GetOwner(),new List<Entity>() { e}));
|
||||||
|
});*/
|
||||||
|
UpdateShowEntities();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public void UpdateShowEntities()
|
||||||
|
{
|
||||||
|
foreach(Entity en in GetEntityExcludingChar())
|
||||||
|
{
|
||||||
|
if (en.Position.Distance(GetOwner().position) < 200)
|
||||||
|
{
|
||||||
|
if (!en.spawned)
|
||||||
|
{
|
||||||
|
en.spawned = true;
|
||||||
|
GetOwner().Send(new PacketScObjectEnterView(GetOwner(), new List<Entity>() { en }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (en.spawned)
|
||||||
|
{
|
||||||
|
|
||||||
|
en.spawned = false;
|
||||||
|
GetOwner().Send(new PacketScObjectLeaveView(GetOwner(), new List<ulong>() { en.guid }));
|
||||||
|
en.Position=en.BornPos;
|
||||||
|
en.Rotation = en.Rotation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c => c.roleId == ownerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
Campofinale/Game/Spaceship/SpaceshipChar.cs
Normal file
67
Campofinale/Game/Spaceship/SpaceshipChar.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Spaceship
|
||||||
|
{
|
||||||
|
public class SpaceshipChar
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
public string id;
|
||||||
|
public ulong guid;
|
||||||
|
public ulong owner;
|
||||||
|
public string stationedRoomId = "";
|
||||||
|
public float physicalStrength;
|
||||||
|
public int favorability;
|
||||||
|
public bool isWorking;
|
||||||
|
public SpaceshipChar()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public SpaceshipChar(ulong owner, string id)
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
this.guid = (ulong)new Random().NextInt64();
|
||||||
|
|
||||||
|
}
|
||||||
|
public string GetNpcId()
|
||||||
|
{
|
||||||
|
return ResourceManager.spaceShipCharBehaviourTable[id].npcId;
|
||||||
|
}
|
||||||
|
public ScdSpaceshipChar ToSpaceshipChar()
|
||||||
|
{
|
||||||
|
return new ScdSpaceshipChar()
|
||||||
|
{
|
||||||
|
CharId = id,
|
||||||
|
Favorability = favorability,
|
||||||
|
IsWorking = isWorking,
|
||||||
|
PhysicalStrength = physicalStrength,
|
||||||
|
StationedRoomId = stationedRoomId,
|
||||||
|
Skills =
|
||||||
|
{
|
||||||
|
new ScdSpaceshipCharSkill()
|
||||||
|
{
|
||||||
|
Index=1,
|
||||||
|
SkillId="spaceship_skill_acc_charmaterial_produce2_1"
|
||||||
|
},
|
||||||
|
new ScdSpaceshipCharSkill()
|
||||||
|
{
|
||||||
|
Index=0,
|
||||||
|
SkillId="spaceship_skill_acc_all_ps_recovery1_2"
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
90
Campofinale/Game/Spaceship/SpaceshipManager.cs
Normal file
90
Campofinale/Game/Spaceship/SpaceshipManager.cs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Game.Inventory;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Spaceship
|
||||||
|
{
|
||||||
|
public class SpaceshipManager
|
||||||
|
{
|
||||||
|
public Player owner;
|
||||||
|
public List<SpaceshipChar> chars=new();
|
||||||
|
public List<SpaceshipRoom> rooms = new();
|
||||||
|
public SpaceshipManager(Player o)
|
||||||
|
{
|
||||||
|
owner = o;
|
||||||
|
}
|
||||||
|
public SpaceshipChar GetChar(string id)
|
||||||
|
{
|
||||||
|
return chars.Find(c => c.id == id);
|
||||||
|
}
|
||||||
|
public void AddNewCharacter(string id)
|
||||||
|
{
|
||||||
|
if (id.Contains("endmin")) return;
|
||||||
|
SpaceshipChar chara = new(owner.roleId, id);
|
||||||
|
chars.Add(chara);
|
||||||
|
}
|
||||||
|
public void Load()
|
||||||
|
{
|
||||||
|
chars = DatabaseManager.db.LoadSpaceshipChars(owner.roleId);
|
||||||
|
rooms = DatabaseManager.db.LoadSpaceshipRooms(owner.roleId);
|
||||||
|
foreach (var chara in owner.chars)
|
||||||
|
{
|
||||||
|
SpaceshipChar c = GetChar(chara.id);
|
||||||
|
if (c == null && !chara.id.Contains("endmin"))
|
||||||
|
{
|
||||||
|
AddNewCharacter(chara.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(rooms.Count < 1)
|
||||||
|
{
|
||||||
|
rooms.Add(new SpaceshipRoom(owner.roleId,"control_center"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Save()
|
||||||
|
{
|
||||||
|
foreach(SpaceshipChar spaceshipChar in chars)
|
||||||
|
{
|
||||||
|
DatabaseManager.db.UpsertSpaceshipChar(spaceshipChar);
|
||||||
|
}
|
||||||
|
foreach(SpaceshipRoom room in rooms)
|
||||||
|
{
|
||||||
|
DatabaseManager.db.UpsertSpaceshipRoom(room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateStationedChars()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> charAndRoom = new();
|
||||||
|
foreach(SpaceshipRoom room in rooms)
|
||||||
|
{
|
||||||
|
foreach (var c in room.stationedCharList)
|
||||||
|
{
|
||||||
|
charAndRoom.Add(c, room.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach(SpaceshipChar chara in chars)
|
||||||
|
{
|
||||||
|
if (charAndRoom.ContainsKey(chara.id))
|
||||||
|
{
|
||||||
|
chara.stationedRoomId = charAndRoom[chara.id];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chara.stationedRoomId = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
153
Campofinale/Game/Spaceship/SpaceshipRoom.cs
Normal file
153
Campofinale/Game/Spaceship/SpaceshipRoom.cs
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
using MongoDB.Bson;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using MongoDB.Bson.Serialization.IdGenerators;
|
||||||
|
|
||||||
|
namespace Campofinale.Game.Spaceship
|
||||||
|
{
|
||||||
|
public class SpaceshipRoom
|
||||||
|
{
|
||||||
|
[BsonId(IdGenerator = typeof(ObjectIdGenerator))]
|
||||||
|
public ObjectId _id { get; set; }
|
||||||
|
public string id = "";
|
||||||
|
public int level = 1;
|
||||||
|
public List<string> stationedCharList = new();
|
||||||
|
public ulong owner;
|
||||||
|
public SpaceshipRoom()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public SpaceshipRoom(ulong owner, string id)
|
||||||
|
{
|
||||||
|
this.owner = owner;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public bool HasCharWorking()
|
||||||
|
{
|
||||||
|
bool val = false;
|
||||||
|
foreach (string chara in stationedCharList)
|
||||||
|
{
|
||||||
|
SpaceshipChar ch = GetOwner().spaceshipManager.GetChar(chara);
|
||||||
|
if (ch != null)
|
||||||
|
{
|
||||||
|
if (ch.isWorking)
|
||||||
|
{
|
||||||
|
val = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
public int GetType()
|
||||||
|
{
|
||||||
|
SpaceshipRoomInsTable roomInfo = ResourceManager.spaceshipRoomInsTable[id];
|
||||||
|
return roomInfo.roomType;
|
||||||
|
}
|
||||||
|
public Player GetOwner()
|
||||||
|
{
|
||||||
|
return Server.clients.Find(c => c.roleId == owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScdSpaceshipRoom ToRoomProto()
|
||||||
|
{
|
||||||
|
SpaceshipRoomInsTable roomInfo = ResourceManager.spaceshipRoomInsTable[id];
|
||||||
|
ScdSpaceshipRoom room = new()
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
Level = level,
|
||||||
|
Type = roomInfo.roomType,
|
||||||
|
HasCharWorking = HasCharWorking(),
|
||||||
|
StationedCharList =
|
||||||
|
{
|
||||||
|
stationedCharList
|
||||||
|
},
|
||||||
|
LevelUpConditionFlags =
|
||||||
|
{
|
||||||
|
{ id+"_level_"+(level+1),true}
|
||||||
|
},
|
||||||
|
LevelUpConditonValues =
|
||||||
|
{
|
||||||
|
{ id+"_level_"+(level+1),4}
|
||||||
|
},
|
||||||
|
AttrsMap =
|
||||||
|
{
|
||||||
|
{0, new ScdSpaceshipRoomAttr()
|
||||||
|
{
|
||||||
|
Value=24.8f,
|
||||||
|
TheoreticalValue=24.8f,
|
||||||
|
BaseAttrs =
|
||||||
|
{
|
||||||
|
new ScdSpaceshipRoomAttrUnit()
|
||||||
|
{
|
||||||
|
Value=20,
|
||||||
|
|
||||||
|
Source = new()
|
||||||
|
{
|
||||||
|
SourceType=1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PercentAttrs =
|
||||||
|
{
|
||||||
|
new ScdSpaceshipRoomAttrUnit()
|
||||||
|
{
|
||||||
|
Value=0.24f,
|
||||||
|
Source = new()
|
||||||
|
{
|
||||||
|
CharId="chr_0004_pelica",
|
||||||
|
SkillId="spaceship_skill_acc_all_ps_recovery1_2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} },
|
||||||
|
{1, new ScdSpaceshipRoomAttr()
|
||||||
|
{
|
||||||
|
Value=12,
|
||||||
|
TheoreticalValue=12,
|
||||||
|
BaseAttrs =
|
||||||
|
{
|
||||||
|
new ScdSpaceshipRoomAttrUnit()
|
||||||
|
{
|
||||||
|
Type=1,
|
||||||
|
Value=12,
|
||||||
|
Source = new()
|
||||||
|
{
|
||||||
|
SourceType=1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
switch (roomInfo.roomType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
room.ControlCenter = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
room.ManufacturingStation = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
room.GrowCabin = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
Campofinale/Game/Team.cs
Normal file
15
Campofinale/Game/Team.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Campofinale.Game
|
||||||
|
{
|
||||||
|
public class Team
|
||||||
|
{
|
||||||
|
public string name = "";
|
||||||
|
public ulong leader;
|
||||||
|
public List<ulong> members = new();
|
||||||
|
}
|
||||||
|
}
|
295
Campofinale/Http/Dispatch.cs
Normal file
295
Campofinale/Http/Dispatch.cs
Normal file
File diff suppressed because one or more lines are too long
82
Campofinale/Http/PCDispatch.cs
Normal file
82
Campofinale/Http/PCDispatch.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
using Campofinale.Commands;
|
||||||
|
using Campofinale.Commands.Handlers;
|
||||||
|
using Campofinale.Database;
|
||||||
|
using HttpServerLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Campofinale.Http
|
||||||
|
{
|
||||||
|
public class PCDispatch
|
||||||
|
{
|
||||||
|
//using as console for player
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.GET, "/pcSdk/userInfo")]
|
||||||
|
public static async Task Info(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string resp = File.ReadAllText("Data/PlayerConsole/index.html").Replace("%dispatchip%", $"http://{Server.config.dispatchServer.accessAddress}:{Server.config.dispatchServer.accessPort}");
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
ctx.Response.ContentType = "text/html";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.GET, "/pcSdk/console")]
|
||||||
|
public static async Task ConsoleResponce(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string cmd = ctx.Request.Query.Elements["command"].Replace("+"," ");
|
||||||
|
string token = ctx.Request.Query.Elements["token"];
|
||||||
|
string message = "";
|
||||||
|
string[] split = cmd.Split(" ");
|
||||||
|
string[] args = cmd.Split(" ").Skip(1).ToArray();
|
||||||
|
string command = split[0].ToLower();
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
Account account = DatabaseManager.db.GetAccountByToken(token);
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
Logger.Print(account.id);
|
||||||
|
Player player = Server.clients.Find(acc => acc.accountId == account.id);
|
||||||
|
if (player != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
CommandManager.Notify(player, command, args, player);
|
||||||
|
foreach (string msg in player.temporanyChatMessages)
|
||||||
|
{
|
||||||
|
message += msg + "<br>";
|
||||||
|
}
|
||||||
|
player.temporanyChatMessages.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = "You aren't connected to the server";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
message = "Account not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else message = "Token not found";
|
||||||
|
|
||||||
|
var responseData = new
|
||||||
|
{
|
||||||
|
message = message,
|
||||||
|
};
|
||||||
|
|
||||||
|
string resp = System.Text.Json.JsonSerializer.Serialize(responseData);
|
||||||
|
ctx.Response.Headers.Add("Content-Type", "application/json");
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
276
Campofinale/Http/SDK.cs
Normal file
276
Campofinale/Http/SDK.cs
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using HttpServerLite;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static Campofinale.Game.Gacha.GachaManager;
|
||||||
|
using static Campofinale.Http.Dispatch;
|
||||||
|
|
||||||
|
namespace Campofinale.Http
|
||||||
|
{
|
||||||
|
public class SDK
|
||||||
|
{
|
||||||
|
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/info/v1/authenticate")]
|
||||||
|
public static async Task cn_authenticate(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
Console.WriteLine(requestBody);
|
||||||
|
string resp = "{}";
|
||||||
|
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
//ctx.Response.ContentLength = resp.Length;
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/auth/v1/token_by_phone_password")]
|
||||||
|
public static async Task token_login_phone_cn(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
LoginJson body = Newtonsoft.Json.JsonConvert.DeserializeObject<LoginJson>(requestBody);
|
||||||
|
Account account = DatabaseManager.db.GetAccountByUsername(body.phone);
|
||||||
|
Console.WriteLine(requestBody);
|
||||||
|
string resp = "{}";
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
resp = "{\"msg\":\"OK\",\"status\":0,\"type\":\"A\",\"data\":{\"token\":\"" + account.token + "\"}}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp = "{\"msg\":\"Account not found\",\"status\":2,\"type\":\"A\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
//ctx.Response.ContentLength = resp.Length;
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/auth/v1/token_by_email_password")]
|
||||||
|
public static async Task token_login(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
LoginJson body = Newtonsoft.Json.JsonConvert.DeserializeObject<LoginJson>(requestBody);
|
||||||
|
Account account = DatabaseManager.db.GetAccountByUsername(body.email.Split("@")[0]);
|
||||||
|
Console.WriteLine(requestBody);
|
||||||
|
string resp = "{}";
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
resp = "{\"msg\":\"OK\",\"status\":0,\"type\":\"A\",\"data\":{\"token\":\"" + account.token + "\"}}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp = "{\"msg\":\"Account not found\",\"status\":2,\"type\":\"A\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
//ctx.Response.ContentLength = resp.Length;
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.GET, "/user/info/v1/basic")]
|
||||||
|
public static async Task account_info_get(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestToken = ctx.Request.Query.Elements["token"];
|
||||||
|
Account account = DatabaseManager.db.GetAccountByToken(requestToken);
|
||||||
|
string resp = "{\"data\":{\"hgId\":\"1799321925\",\"email\":\"dispatch@endfield.ps\",\"realEmail\":\"dispatch@endfield.ps\",\"isLatestUserAgreement\":true,\"nickName\":\"Campofinale\"},\"msg\":\"OK\",\"status\":0,\"type\":1}";
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
resp = "{\"data\":{\"idCardNum\": 110102200610048887,\"hgId\":\"" + account.id + "\",\"email\":\"" + account.username +Server.config.dispatchServer.emailFormat +"\",\"realEmail\":\"" + account.username + Server.config.dispatchServer.emailFormat + "\",\"isLatestUserAgreement\":true,\"nickName\":\"" + account.username + "\",\"name\":\"AAAA\"},\"msg\":\"OK\",\"status\":0,\"type\":1}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp = "{\"msg\":\"Account not found\",\"status\":2,\"type\":\"A\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
//ctx.Response.ContentLength = resp.Length;
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct GrantData
|
||||||
|
{
|
||||||
|
public string token;
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/oauth2/v2/grant")]
|
||||||
|
public static async Task account_ugrant(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
|
||||||
|
GrantData grant = Newtonsoft.Json.JsonConvert.DeserializeObject<GrantData>(requestBody);
|
||||||
|
Account account = DatabaseManager.db.GetAccountByToken(grant.token);
|
||||||
|
string resp = "{\"msg\": \"Error\", \"status\": 2, \"type\": \"A\"}";
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
resp = "{\"data\": { \"uid\": \"" + account.id + "\", \"code\": \"" + DatabaseManager.db.GrantCode(account) + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/u8/user/auth/v2/grant")]
|
||||||
|
public static async Task account_grant(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
|
||||||
|
GrantData grant = Newtonsoft.Json.JsonConvert.DeserializeObject<GrantData>(requestBody);
|
||||||
|
Account account = DatabaseManager.db.GetAccountByTokenGrant(grant.token);
|
||||||
|
string resp = "{\"msg\": \"Error\", \"status\": 2, \"type\": \"A\"}";
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
resp = "{\"data\": { \"uid\": \"" + account.id + "\", \"code\": \"" + account.grantToken + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TokenChannelData
|
||||||
|
{
|
||||||
|
public string channelToken;
|
||||||
|
|
||||||
|
}
|
||||||
|
public class ChannelTokenData
|
||||||
|
{
|
||||||
|
public string code;
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/u8/user/auth/v2/token_by_channel_token")]
|
||||||
|
public static async Task token_channel_token(HttpContext ctx)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
Console.WriteLine(requestBody);
|
||||||
|
TokenChannelData data = Newtonsoft.Json.JsonConvert.DeserializeObject<TokenChannelData>(requestBody);
|
||||||
|
ChannelTokenData channelTokenBody = Newtonsoft.Json.JsonConvert.DeserializeObject<ChannelTokenData>(data.channelToken);
|
||||||
|
string resp = "{ \"data\": { \"token\":\"" + channelTokenBody.code + "\" }, \"msg\": \"OK\", \"status\": 0, \"type\": \"A\"}";
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*{
|
||||||
|
"appCode": "2fe67ec91610377d",
|
||||||
|
"code": "121212",
|
||||||
|
"email": "aaaa@a.cc",
|
||||||
|
"from": 0,
|
||||||
|
"password": "aaaaaaaaaaaaaa1"
|
||||||
|
}*/
|
||||||
|
public struct RegisterData
|
||||||
|
{
|
||||||
|
public string appCode;
|
||||||
|
public string code;
|
||||||
|
public string email;
|
||||||
|
public string password;
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.POST, "/user/auth/v1/register")]
|
||||||
|
public static async Task register(HttpContext ctx)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string requestBody = ctx.Request.DataAsString;
|
||||||
|
Console.WriteLine(requestBody);
|
||||||
|
RegisterData data = Newtonsoft.Json.JsonConvert.DeserializeObject<RegisterData>(requestBody);
|
||||||
|
string username = data.email.Split("@")[0];
|
||||||
|
(string,int) msg=DatabaseManager.db.CreateAccount(username);
|
||||||
|
string resp = "";
|
||||||
|
if (msg.Item2 > 0)
|
||||||
|
{
|
||||||
|
resp = "{\"msg\": \"" + msg.Item1 + "\", \"status\": " + msg.Item2 + ", \"type\": \"\"}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Account account = DatabaseManager.db.GetAccountByUsername(username);
|
||||||
|
resp = "{\"data\": { \"token\":\"" + account.token + "\" }, \"msg\": \"" + msg.Item1 + "\", \"status\": " + msg.Item2 + ", \"type\": \"\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
ctx.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError(e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.GET, "/api/gachahistory")]
|
||||||
|
public static async Task gachahistory_api(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestId = ctx.Request.Query.Elements["id"];
|
||||||
|
string banner = ctx.Request.Query.Elements["banner"];
|
||||||
|
string page = ctx.Request.Query.Elements["page"];
|
||||||
|
PlayerData data = DatabaseManager.db.GetPlayerById(requestId);
|
||||||
|
GachaHistoryAPI transactions = new();
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
transactions = GetGachaHistoryPage(data, banner, int.Parse(page));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
transactions.transactionList = new();
|
||||||
|
}
|
||||||
|
string resp = Newtonsoft.Json.JsonConvert.SerializeObject(transactions);
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
[StaticRoute(HttpServerLite.HttpMethod.GET, "/gachahistory")]
|
||||||
|
public static async Task gachahistory(HttpContext ctx)
|
||||||
|
{
|
||||||
|
string requestId = ctx.Request.Query.Elements["id"];
|
||||||
|
|
||||||
|
PlayerData data = DatabaseManager.db.GetPlayerById(requestId);
|
||||||
|
string resp = "";
|
||||||
|
if (data != null)
|
||||||
|
{
|
||||||
|
resp = File.ReadAllText("Data/GachaHistory/index.html").Replace("%dispatchip%", $"http://{Server.config.dispatchServer.accessAddress}:{Server.config.dispatchServer.accessPort}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resp = File.ReadAllText("Data/GachaHistory/index_noplayerfound.html");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ctx.Response.StatusCode = 200;
|
||||||
|
|
||||||
|
await ctx.Response.SendAsync(resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
79
Campofinale/Logger.cs
Normal file
79
Campofinale/Logger.cs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
using Campofinale;
|
||||||
|
using Pastel;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
public static class Logger
|
||||||
|
{
|
||||||
|
|
||||||
|
public static Dictionary<string, string> ClassColors = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{"Server","03fcce" },
|
||||||
|
{"Dispatch", "0307fc" }
|
||||||
|
};
|
||||||
|
private static string GetCallingClassName()
|
||||||
|
{
|
||||||
|
StackTrace stackTrace = new StackTrace();
|
||||||
|
|
||||||
|
var frame = stackTrace.GetFrame(2);
|
||||||
|
var method = frame?.GetMethod();
|
||||||
|
return method?.DeclaringType?.Name ?? "Server";
|
||||||
|
}
|
||||||
|
public static void Print(string text)
|
||||||
|
{
|
||||||
|
string className = GetCallingClassName();
|
||||||
|
Logger.Log(text);
|
||||||
|
string prefix = "<" + "INFO".Pastel("03fcce") + $":{className.Pastel("999")}>";
|
||||||
|
Console.WriteLine($"{prefix} " + text);
|
||||||
|
}
|
||||||
|
public static void PrintError(string text)
|
||||||
|
{
|
||||||
|
string className = GetCallingClassName();
|
||||||
|
Logger.Log(text);
|
||||||
|
string prefix = "<" + "ERROR".Pastel("eb4034") + $":{className.Pastel("999")}>";
|
||||||
|
Console.WriteLine($"{prefix} " + text.Pastel("917e7e"));
|
||||||
|
}
|
||||||
|
public static void PrintWarn(string text)
|
||||||
|
{
|
||||||
|
string className = GetCallingClassName();
|
||||||
|
Logger.Log(text);
|
||||||
|
string prefix = "<" + "WARN".Pastel("ff9100") + $":{className.Pastel("999")}>";
|
||||||
|
Console.WriteLine($"{prefix} " + text);
|
||||||
|
}
|
||||||
|
public static string GetColor(string c)
|
||||||
|
{
|
||||||
|
if (ClassColors.ContainsKey(c)) return ClassColors[c];
|
||||||
|
return "999";
|
||||||
|
}
|
||||||
|
private static StreamWriter logWriter;
|
||||||
|
private static bool hideLogs;
|
||||||
|
|
||||||
|
public static void Initialize(bool hideLogs = false)
|
||||||
|
{
|
||||||
|
Logger.hideLogs = hideLogs;
|
||||||
|
logWriter = new StreamWriter("latest.log", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Log(string message)
|
||||||
|
{
|
||||||
|
if (!hideLogs)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logWriter.WriteLine($"{DateTime.Now}: {message}");
|
||||||
|
logWriter.Flush();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Close()
|
||||||
|
{
|
||||||
|
logWriter.Close();
|
||||||
|
}
|
||||||
|
}
|
193
Campofinale/Network/Packet.cs
Normal file
193
Campofinale/Network/Packet.cs
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using Pastel;
|
||||||
|
using System;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||||
|
|
||||||
|
namespace Campofinale.Network
|
||||||
|
{
|
||||||
|
public class Packet
|
||||||
|
{
|
||||||
|
public int cmdId;
|
||||||
|
public byte[] finishedBody;
|
||||||
|
public CSHead csHead;
|
||||||
|
public IMessage set_body;
|
||||||
|
public static void PutUInt16(byte[] buf, ushort networkValue, int offset)
|
||||||
|
{
|
||||||
|
byte[] bytes = BitConverter.GetBytes(networkValue);
|
||||||
|
Buffer.BlockCopy(bytes, 0, buf, offset, bytes.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PutUInt32(byte[] buf, uint networkValue, int offset)
|
||||||
|
{
|
||||||
|
byte[] bytes = BitConverter.GetBytes(networkValue);
|
||||||
|
Buffer.BlockCopy(bytes, 0, buf, offset, bytes.Length);
|
||||||
|
}
|
||||||
|
public static void PutUInt64(byte[] buf, ulong networkValue, int offset)
|
||||||
|
{
|
||||||
|
byte[] bytes = BitConverter.GetBytes(networkValue);
|
||||||
|
Buffer.BlockCopy(bytes, 0, buf, offset, bytes.Length);
|
||||||
|
}
|
||||||
|
public static ushort GetUInt16(byte[] buf, int index)
|
||||||
|
{
|
||||||
|
ushort networkValue = BitConverter.ToUInt16(buf, index);
|
||||||
|
return networkValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetUInt32(byte[] buf,int index)
|
||||||
|
{
|
||||||
|
uint networkValue = BitConverter.ToUInt32(buf, index);
|
||||||
|
return (uint)IPAddress.NetworkToHostOrder((int)networkValue);
|
||||||
|
}
|
||||||
|
public static void PutByte(byte[] buf, byte networkValue, int offset)
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[1] {networkValue };
|
||||||
|
Buffer.BlockCopy(bytes, 0, buf, offset, bytes.Length);
|
||||||
|
}
|
||||||
|
public static byte GetByte(byte[] buf, int index)
|
||||||
|
{
|
||||||
|
byte networkValue = buf[index];
|
||||||
|
return networkValue;
|
||||||
|
}
|
||||||
|
public TBody DecodeBody<TBody>() where TBody : IMessage<TBody>, new()
|
||||||
|
{
|
||||||
|
return new MessageParser<TBody>(() => new()).ParseFrom(finishedBody);
|
||||||
|
}
|
||||||
|
public static void PutByteArray(byte[] destination, byte[] source, int offset)
|
||||||
|
{
|
||||||
|
if (destination == null)
|
||||||
|
throw new ArgumentNullException(nameof(destination));
|
||||||
|
if (source == null)
|
||||||
|
throw new ArgumentNullException(nameof(source));
|
||||||
|
if (offset < 0 || offset > destination.Length - source.Length)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(offset), "Offset is out of range.");
|
||||||
|
|
||||||
|
Buffer.BlockCopy(source, 0, destination, offset, source.Length);
|
||||||
|
}
|
||||||
|
public static byte[] ToByteArray(IntPtr ptr, int length)
|
||||||
|
{
|
||||||
|
if (ptr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Pointer cannot be null", nameof(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] byteArray = new byte[length];
|
||||||
|
Marshal.Copy(ptr, byteArray, 0, length);
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
public static IntPtr ByteArrayToIntPtr(byte[] data)
|
||||||
|
{
|
||||||
|
if (data == null) throw new ArgumentNullException(nameof(data));
|
||||||
|
|
||||||
|
// Allocate unmanaged memory
|
||||||
|
IntPtr ptr = Marshal.AllocHGlobal(data.Length);
|
||||||
|
|
||||||
|
// Copy the byte array to the unmanaged memory
|
||||||
|
Marshal.Copy(data, 0, ptr, data.Length);
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
public static byte[] EncryptWithPublicKey(byte[] data, string publicKey)
|
||||||
|
{
|
||||||
|
// Crea un oggetto RSA
|
||||||
|
using (RSA rsa = RSA.Create())
|
||||||
|
{
|
||||||
|
|
||||||
|
publicKey = publicKey.Replace("-----BEGIN PUBLIC KEY-----", "");
|
||||||
|
publicKey = publicKey.Replace("\r", "");
|
||||||
|
publicKey = publicKey.Replace("\n", "");
|
||||||
|
publicKey = publicKey.Replace("-----END PUBLIC KEY-----", "");
|
||||||
|
publicKey = publicKey.Trim();
|
||||||
|
Logger.Print(publicKey);
|
||||||
|
byte[] publicKey_ = Convert.FromBase64String(publicKey);
|
||||||
|
// Importa la chiave pubblica
|
||||||
|
rsa.ImportSubjectPublicKeyInfo(publicKey_, out _);
|
||||||
|
|
||||||
|
// Crittografa i dati
|
||||||
|
return rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Packet SetData(ScMsgId msgId, IMessage body)
|
||||||
|
{
|
||||||
|
set_body = body;
|
||||||
|
cmdId = (int)msgId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public static byte[] EncodePacket(Packet packet,ulong seq = 0, uint totalPackCount = 1, uint currentPackIndex = 0)
|
||||||
|
{
|
||||||
|
return EncodePacket(packet.cmdId,packet.set_body,seq, totalPackCount, currentPackIndex);
|
||||||
|
}
|
||||||
|
public static ulong seqNext = 1;
|
||||||
|
public static byte[] EncodePacket(int msgId, IMessage body, ulong seqNext_ = 0, uint totalPackCount=1,uint currentPackIndex=0)
|
||||||
|
{
|
||||||
|
if (seqNext_ == 0)
|
||||||
|
{
|
||||||
|
seqNext_ = seqNext;
|
||||||
|
}
|
||||||
|
seqNext++;
|
||||||
|
CSHead head = new() { Msgid = msgId,UpSeqid=seqNext_, DownSeqid= seqNext, TotalPackCount= totalPackCount, CurrentPackIndex= currentPackIndex };
|
||||||
|
int totalSerializedDataSize = 3 + head.ToByteArray().Length + body.ToByteArray().Length;
|
||||||
|
byte[] data = new byte[totalSerializedDataSize];
|
||||||
|
PutByte(data, (byte)head.ToByteArray().Length, 0);
|
||||||
|
PutUInt16(data, (ushort)body.ToByteArray().Length, 1);
|
||||||
|
PutByteArray(data, head.ToByteArray(), 3);
|
||||||
|
PutByteArray(data, body.ToByteArray(), 3+head.ToByteArray().Length);
|
||||||
|
if(Server.config.logOptions.packets && !Server.scMessageToHide.Contains((ScMsgId)msgId))
|
||||||
|
Logger.Print($"Sending packet: {((ScMsgId)msgId).ToString().Pastel(Color.LightBlue)} id: {msgId} with {data.Length} bytes");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
public static byte[] EncodePacket(int msgId, byte[] body, ulong seqNext_ = 0, uint totalPackCount = 1, uint currentPackIndex = 0)
|
||||||
|
{
|
||||||
|
if (seqNext_ == 0)
|
||||||
|
{
|
||||||
|
seqNext_ = seqNext;
|
||||||
|
}
|
||||||
|
if(currentPackIndex==0)
|
||||||
|
{
|
||||||
|
seqNext++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSHead head = new() { Msgid = msgId, UpSeqid = seqNext_, DownSeqid = seqNext, TotalPackCount = totalPackCount, CurrentPackIndex = currentPackIndex };
|
||||||
|
int totalSerializedDataSize = 3 + head.ToByteArray().Length + body.Length;
|
||||||
|
byte[] data = new byte[totalSerializedDataSize];
|
||||||
|
PutByte(data, (byte)head.ToByteArray().Length, 0);
|
||||||
|
PutUInt16(data, (ushort)body.Length, 1);
|
||||||
|
PutByteArray(data, head.ToByteArray(), 3);
|
||||||
|
PutByteArray(data, body, 3 + head.ToByteArray().Length);
|
||||||
|
if (Server.config.logOptions.packets && !Server.scMessageToHide.Contains((ScMsgId)msgId))
|
||||||
|
Logger.Print($"Sending packet: {((ScMsgId)msgId).ToString().Pastel(Color.LightBlue)} id: {msgId} with {data.Length} bytes");
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
public static Packet Read(Player client,byte[] byteArray)
|
||||||
|
{
|
||||||
|
byte headLength = GetByte(byteArray, 0);
|
||||||
|
ushort bodyLength = GetUInt16(byteArray, 1);
|
||||||
|
|
||||||
|
byte[] csHeadBytes = new byte[headLength];
|
||||||
|
byte[] BodyBytes = new byte[bodyLength];
|
||||||
|
Array.Copy(byteArray, 3, csHeadBytes, 0, headLength);
|
||||||
|
Array.Copy(byteArray, 3+ headLength, BodyBytes, 0, bodyLength);
|
||||||
|
CSHead csHead_ = CSHead.Parser.ParseFrom(csHeadBytes);
|
||||||
|
if (Server.config.logOptions.packets)
|
||||||
|
{
|
||||||
|
Logger.Print(csHead_.ToString());
|
||||||
|
}
|
||||||
|
seqNext = csHead_.UpSeqid;
|
||||||
|
return new Packet() { csHead = csHead_, finishedBody = BodyBytes,cmdId=csHead_.Msgid };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
69
Campofinale/NotifyManager.cs
Normal file
69
Campofinale/NotifyManager.cs
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
namespace Campofinale
|
||||||
|
{
|
||||||
|
using Pastel;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Collections.Immutable;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Network;
|
||||||
|
|
||||||
|
internal static class NotifyManager
|
||||||
|
{
|
||||||
|
private static List<Type> s_handlerTypes = new List<Type>();
|
||||||
|
private static ImmutableDictionary<CsMsgId, (Server.HandlerAttribute, Server.HandlerAttribute.HandlerDelegate)> s_notifyReqGroup;
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
var handlers = ImmutableDictionary.CreateBuilder<CsMsgId, (Server.HandlerAttribute, Server.HandlerAttribute.HandlerDelegate)>();
|
||||||
|
|
||||||
|
foreach (var type in s_handlerTypes)
|
||||||
|
{
|
||||||
|
foreach (var method in type.GetMethods())
|
||||||
|
{
|
||||||
|
var attribute = method.GetCustomAttribute<Server.HandlerAttribute>();
|
||||||
|
if (attribute == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var parameterInfo = method.GetParameters();
|
||||||
|
|
||||||
|
var sessionParameter = Expression.Parameter(typeof(Player));
|
||||||
|
var cmdIdParameter = Expression.Parameter(typeof(int));
|
||||||
|
var packetParameter = Expression.Parameter(typeof(Packet));
|
||||||
|
|
||||||
|
var call = Expression.Call(method,
|
||||||
|
Expression.Convert(sessionParameter, parameterInfo[0].ParameterType),
|
||||||
|
Expression.Convert(cmdIdParameter, parameterInfo[1].ParameterType),
|
||||||
|
Expression.Convert(packetParameter, parameterInfo[2].ParameterType));
|
||||||
|
|
||||||
|
var lambda = Expression.Lambda<Server.HandlerAttribute.HandlerDelegate>(call, sessionParameter, cmdIdParameter, packetParameter);
|
||||||
|
|
||||||
|
if (!handlers.TryGetKey(attribute.CmdId, out _))
|
||||||
|
handlers.Add(attribute.CmdId, (attribute, lambda.Compile()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_notifyReqGroup = handlers.ToImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Notify(Player session, CsMsgId cmdId, Network.Packet packet)
|
||||||
|
{
|
||||||
|
if (s_notifyReqGroup.TryGetValue(cmdId, out var handler))
|
||||||
|
{
|
||||||
|
handler.Item2.Invoke(session, ((int)cmdId), packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Server.hideLog.Contains(cmdId) && Server.config.logOptions.packets)
|
||||||
|
Logger.PrintWarn($"Can't find handler for {(Enum.GetName(typeof(CsMsgId), cmdId)).ToString().Pastel(Color.FromArgb(165, 229, 250))} ({(cmdId).ToString().Pastel(Color.FromArgb(165, 229, 250))})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddReqGroupHandler(Type type)
|
||||||
|
{
|
||||||
|
s_handlerTypes.Add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
191
Campofinale/Packets/Cs/HandleCsBattleOp.cs
Normal file
191
Campofinale/Packets/Cs/HandleCsBattleOp.cs
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Game.Entities;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using MongoDB.Driver.Core.Clusters;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsBattleOp
|
||||||
|
{
|
||||||
|
//TODO AbilityManager
|
||||||
|
[Server.Handler(CsMsgId.CsBattleOp)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsBattleOp req = packet.DecodeBody<CsBattleOp>();
|
||||||
|
|
||||||
|
foreach (BattleClientOpData data in req.ClientData.OpList)
|
||||||
|
{
|
||||||
|
switch (data.OpType)
|
||||||
|
{
|
||||||
|
|
||||||
|
case BattleActionOperateType.BattleOpEntityValueModify:
|
||||||
|
OnEntityValueModify(session, data);
|
||||||
|
break;
|
||||||
|
case BattleActionOperateType.BattleOpSkillStartCast:
|
||||||
|
OnSkillStartCast(session, data);
|
||||||
|
break;
|
||||||
|
case BattleActionOperateType.BattleOpSkillEndCast:
|
||||||
|
OnSkillEndCast(session, data);
|
||||||
|
break;
|
||||||
|
case BattleActionOperateType.BattleOpTriggerAction:
|
||||||
|
OnTriggerAction(session, data.TriggerActionOpData);
|
||||||
|
break;
|
||||||
|
case BattleActionOperateType.BattleOpEntityDie:
|
||||||
|
OnEntityDie(session, data.EntityDieOpData);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Logger.PrintWarn($"Unsupported BattleActionOperateType.{data.OpType}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnEntityDie(Player session, BattleEntityDieOpData data)
|
||||||
|
{
|
||||||
|
if (session.sceneManager.GetEntity(data.EntityInstId) != null)
|
||||||
|
{
|
||||||
|
if (Server.config.logOptions.debugPrint)
|
||||||
|
{
|
||||||
|
Logger.PrintWarn("Killed entity with guid: "+data.EntityInstId);
|
||||||
|
}
|
||||||
|
session.sceneManager.KillEntity(data.EntityInstId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnTriggerAction(Player session, BattleTriggerActionOpData data)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (data.Action.ActionType)
|
||||||
|
{
|
||||||
|
case ServerBattleActionType.BattleActionDamage:
|
||||||
|
foreach(BattleDamageDetail item in data.Action.DamageAction.Details)
|
||||||
|
{
|
||||||
|
DamageEntity(session, item);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ServerBattleActionType.BattleActionHeal:
|
||||||
|
foreach (BattleHealActionDetail item in data.Action.HealAction.Details)
|
||||||
|
{
|
||||||
|
HealEntity(session, item);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Logger.PrintWarn($"Unsupported ServerBattleActionType.{data.Action.ActionType}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void HealEntity(Player session, BattleHealActionDetail detail)
|
||||||
|
{
|
||||||
|
Entity en = session.sceneManager.GetEntity(detail.TargetId);
|
||||||
|
if (en != null)
|
||||||
|
{
|
||||||
|
Logger.Print("Healing +" + detail.Value + "hp");
|
||||||
|
en.Heal(detail.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DamageEntity(Player session, BattleDamageDetail detail)
|
||||||
|
{
|
||||||
|
Entity en=session.sceneManager.GetEntity(detail.TargetId);
|
||||||
|
|
||||||
|
if (en != null)
|
||||||
|
{
|
||||||
|
en.Damage(detail.Value);
|
||||||
|
if (Server.config.logOptions.debugPrint)
|
||||||
|
{
|
||||||
|
Logger.PrintWarn("Damaged entity with dmg: "+detail.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void OnSkillStartCast(Player session, BattleClientOpData data)
|
||||||
|
{
|
||||||
|
ulong casterId = data.OwnerId;
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c => c.guid == casterId);
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
ScCharSyncStatus s = new()
|
||||||
|
{
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp = character.curHp,
|
||||||
|
Ultimatesp = character.ultimateSp
|
||||||
|
},
|
||||||
|
Objid=character.guid,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
session.Send(ScMsgId.ScCharSyncStatus, s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Manage normal entity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static void OnSkillEndCast(Player session, BattleClientOpData data)
|
||||||
|
{
|
||||||
|
ulong casterId = data.OwnerId;
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c => c.guid == casterId);
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
ScCharSyncStatus s = new()
|
||||||
|
{
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp = character.curHp,
|
||||||
|
Ultimatesp = character.ultimateSp+1
|
||||||
|
},
|
||||||
|
Objid = character.guid,
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScCharSyncStatus, s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Manage normal entity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnEntityValueModify(Player session, BattleClientOpData data)
|
||||||
|
{
|
||||||
|
Logger.PrintWarn("EntityValueModify called: " + data.EntityValueModifyData.ToString());
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c => c.guid == data.EntityValueModifyData.EntityInstId);
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
character.curHp = data.EntityValueModifyData.Value.Hp;
|
||||||
|
ScCharSyncStatus s = new()
|
||||||
|
{
|
||||||
|
BattleInfo = new()
|
||||||
|
{
|
||||||
|
Hp = data.EntityValueModifyData.Value.Hp,
|
||||||
|
Ultimatesp = character.ultimateSp
|
||||||
|
},
|
||||||
|
Objid = character.guid,
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScCharSyncStatus, s);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Manage normal entity
|
||||||
|
}
|
||||||
|
// data.EntityValueModifyData.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
Campofinale/Packets/Cs/HandleCsBitsetAdd.cs
Normal file
34
Campofinale/Packets/Cs/HandleCsBitsetAdd.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsBitsetAdd
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsBitsetAdd)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsBitsetAdd req = packet.DecodeBody<CsBitsetAdd>();
|
||||||
|
foreach (var item in req.Value)
|
||||||
|
{
|
||||||
|
session.bitsetManager.AddValue((BitsetType)req.Type, (int)item);
|
||||||
|
}
|
||||||
|
session.Send(new PacketScBitsetAdd(session,req.Type,req.Value.ToList()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
34
Campofinale/Packets/Cs/HandleCsBitsetRemove.cs
Normal file
34
Campofinale/Packets/Cs/HandleCsBitsetRemove.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsBitsetRemove
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsBitsetRemove)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsBitsetRemove req = packet.DecodeBody<CsBitsetRemove>();
|
||||||
|
foreach (var item in req.Value)
|
||||||
|
{
|
||||||
|
session.bitsetManager.RemoveValue((BitsetType)req.Type, (int)item);
|
||||||
|
}
|
||||||
|
session.Send(new PacketScBitsetRemove(session,req.Type,req.Value.ToList()));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
36
Campofinale/Packets/Cs/HandleCsCharBagSetCurrTeamIndex.cs
Normal file
36
Campofinale/Packets/Cs/HandleCsCharBagSetCurrTeamIndex.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using BeyondTools.VFS.Crypto;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
|
||||||
|
public class HandleCsCharBagSetCurrTeamIndex
|
||||||
|
{
|
||||||
|
[Server.Handler(CsMsgId.CsCharBagSetCurrTeamIndex)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharBagSetCurrTeamIndex req = packet.DecodeBody<CsCharBagSetCurrTeamIndex>();
|
||||||
|
session.teamIndex = req.TeamIndex;
|
||||||
|
session.teams[session.teamIndex].leader = req.LeaderId;
|
||||||
|
|
||||||
|
session.Send(new PacketScCharBagSetCurrTeamIndex(session));
|
||||||
|
session.Send(new PacketScSelfSceneInfo(session,SelfInfoReasonType.SlrChangeTeam));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs
Normal file
40
Campofinale/Packets/Cs/HandleCsCharBagSetTeam.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharBagSetTeam
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsCharBagSetTeam)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharBagSetTeam req = packet.DecodeBody<CsCharBagSetTeam>();
|
||||||
|
|
||||||
|
session.teams[req.TeamIndex].leader=req.LeaderId;
|
||||||
|
session.teams[req.TeamIndex].members= req.CharTeam.ToList();
|
||||||
|
ScCharBagSetTeam team = new()
|
||||||
|
{
|
||||||
|
CharTeam = { req.CharTeam },
|
||||||
|
LeaderId = req.LeaderId,
|
||||||
|
ScopeName = 1,
|
||||||
|
TeamIndex = req.TeamIndex,
|
||||||
|
TeamType = CharBagTeamType.Main,
|
||||||
|
};
|
||||||
|
|
||||||
|
session.Send(ScMsgId.ScCharBagSetTeam,team);
|
||||||
|
session.Send(new PacketScSelfSceneInfo(session, Resource.SelfInfoReasonType.SlrChangeTeam));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
37
Campofinale/Packets/Cs/HandleCsCharBagSetTeamLeader.cs
Normal file
37
Campofinale/Packets/Cs/HandleCsCharBagSetTeamLeader.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharBagSetTeamLeader
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsCharBagSetTeamLeader)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharBagSetTeamLeader req = packet.DecodeBody<CsCharBagSetTeamLeader>();
|
||||||
|
|
||||||
|
session.teams[req.TeamIndex].leader=req.Leaderid;
|
||||||
|
ScCharBagSetTeamLeader rsp = new()
|
||||||
|
{
|
||||||
|
Leaderid = req.Leaderid,
|
||||||
|
TeamIndex = req.TeamIndex,
|
||||||
|
ScopeName = 1,
|
||||||
|
TeamType = req.TeamType,
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScCharBagSetTeamLeader, rsp);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
Campofinale/Packets/Cs/HandleCsCharBagSetTeamName.cs
Normal file
35
Campofinale/Packets/Cs/HandleCsCharBagSetTeamName.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharBagSetTeamName
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsCharBagSetTeamName)]
|
||||||
|
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharBagSetTeamName req = packet.DecodeBody<CsCharBagSetTeamName>();
|
||||||
|
|
||||||
|
session.teams[req.TeamIndex].name=req.TeamName;
|
||||||
|
|
||||||
|
ScCharBagSetTeamName rsp = new()
|
||||||
|
{
|
||||||
|
TeamIndex = req.TeamIndex,
|
||||||
|
TeamName = req.TeamName,
|
||||||
|
ScopeName = 1,
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScCharBagSetTeamName, rsp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
Campofinale/Packets/Cs/HandleCsCharLevelUp.cs
Normal file
31
Campofinale/Packets/Cs/HandleCsCharLevelUp.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharLevelUp
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsCharLevelUp)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharLevelUp req = packet.DecodeBody<CsCharLevelUp>();
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c=>c.guid==req.CharObjID);
|
||||||
|
if(character!=null)
|
||||||
|
character.LevelUp(req.Items);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs
Normal file
42
Campofinale/Packets/Cs/HandleCsCharPotentialUnlock.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharPotentialUnlock
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsCharPotentialUnlock)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharPotentialUnlock req = packet.DecodeBody<CsCharPotentialUnlock>();
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c => c.guid == req.CharObjId);
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
character.potential=req.Level;
|
||||||
|
//TODO consume Item ID
|
||||||
|
|
||||||
|
ScCharPotentialUnlock unlock = new()
|
||||||
|
{
|
||||||
|
CharObjId = req.CharObjId,
|
||||||
|
Level = req.Level,
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScCharPotentialUnlock, unlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
32
Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs
Normal file
32
Campofinale/Packets/Cs/HandleCsCharUnlockTalentNode.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsCharUnlockTalentNode
|
||||||
|
{
|
||||||
|
[Server.Handler(CsMsgId.CsCharUnlockTalentNode)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCharUnlockTalentNode req = packet.DecodeBody<CsCharUnlockTalentNode>();
|
||||||
|
|
||||||
|
Character character = session.chars.Find(c=>c.guid==req.CharObjId);
|
||||||
|
if (character != null)
|
||||||
|
{
|
||||||
|
character.UnlockNode(req.NodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
27
Campofinale/Packets/Cs/HandleCsEnterDungeon.cs
Normal file
27
Campofinale/Packets/Cs/HandleCsEnterDungeon.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsEnterDungeon
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsEnterDungeon)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsEnterDungeon req = packet.DecodeBody<CsEnterDungeon>();
|
||||||
|
session.EnterDungeon(req.DungeonId, req.RacingParam);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
44
Campofinale/Packets/Cs/HandleCsEquipPutoff.cs
Normal file
44
Campofinale/Packets/Cs/HandleCsEquipPutoff.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsEquipPutoff
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsEquipPutoff)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsEquipPutoff req = packet.DecodeBody<CsEquipPutoff>();
|
||||||
|
Character toRemove = session.chars.Find(c => c.guid == req.Charid);
|
||||||
|
if (toRemove != null)
|
||||||
|
{
|
||||||
|
ScEquipPutoff put = new()
|
||||||
|
{
|
||||||
|
Charid = req.Charid,
|
||||||
|
Slotid = req.Slotid,
|
||||||
|
|
||||||
|
};
|
||||||
|
if (toRemove != null)
|
||||||
|
{
|
||||||
|
toRemove.equipCol[req.Slotid] = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
//TODO Improve all this maybe with an internal method in Character
|
||||||
|
session.Send(ScMsgId.ScEquipPutoff, put);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
47
Campofinale/Packets/Cs/HandleCsEquipPuton.cs
Normal file
47
Campofinale/Packets/Cs/HandleCsEquipPuton.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using Campofinale.Game.Character;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsEquipPuton
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsEquipPuton)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsEquipPuton req = packet.DecodeBody<CsEquipPuton>();
|
||||||
|
Character toEquip = session.chars.Find(c => c.guid == req.Charid);
|
||||||
|
Character toRemove = session.chars.Find(c => c.IsEquipped(req.Equipid));
|
||||||
|
if (toEquip != null)
|
||||||
|
{
|
||||||
|
ScEquipPuton put = new()
|
||||||
|
{
|
||||||
|
Charid = req.Charid,
|
||||||
|
Equipid = req.Equipid,
|
||||||
|
Slotid = req.Slotid,
|
||||||
|
|
||||||
|
};
|
||||||
|
if (toRemove != null)
|
||||||
|
{
|
||||||
|
toRemove.equipCol[req.Slotid] = toEquip.equipCol[req.Slotid];
|
||||||
|
put.PutOffCharid = toRemove.guid;
|
||||||
|
}
|
||||||
|
toEquip.equipCol[req.Slotid] = req.Equipid;
|
||||||
|
//TODO Improve all this maybe with an internal method in Character
|
||||||
|
session.Send(ScMsgId.ScEquipPuton, put);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
34
Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs
Normal file
34
Campofinale/Packets/Cs/HandleCsFactoryHsFb.cs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsFactoryHsFb
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsFactoryHsFb)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsFactoryHsFb req = packet.DecodeBody<CsFactoryHsFb>();
|
||||||
|
long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds();
|
||||||
|
|
||||||
|
ScFactoryHs hs = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScFactoryHs, hs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
26
Campofinale/Packets/Cs/HandleCsFactoryOp.cs
Normal file
26
Campofinale/Packets/Cs/HandleCsFactoryOp.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsFactoryOp
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsFactoryOp)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsFactoryOp req = packet.DecodeBody<CsFactoryOp>();
|
||||||
|
session.factoryManager.ExecOp(req,packet.csHead.UpSeqid);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
33
Campofinale/Packets/Cs/HandleCsFactoryStatisticRequire.cs
Normal file
33
Campofinale/Packets/Cs/HandleCsFactoryStatisticRequire.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsFactoryStatisticRequire
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsFactoryStatisticRequire)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsFactoryStatisticRequire req = packet.DecodeBody<CsFactoryStatisticRequire>();
|
||||||
|
ScFactoryStatisticRequire rsp = new()
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
session.Send(ScMsgId.ScFactoryStatisticRequire, rsp);
|
||||||
|
|
||||||
|
//Logger.Print("Server: " + curtimestamp + " client: " + req.ClientTs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
31
Campofinale/Packets/Cs/HandleCsFinishDialog.cs
Normal file
31
Campofinale/Packets/Cs/HandleCsFinishDialog.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsFinishDialog
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsFinishDialog)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsFinishDialog req = packet.DecodeBody<CsFinishDialog>();
|
||||||
|
session.Send(ScMsgId.ScFinishDialog, new ScFinishDialog()
|
||||||
|
{
|
||||||
|
DialogId=req.DialogId,
|
||||||
|
FinishNums = { req.FinishNums },
|
||||||
|
OptionIds = { req.OptionIds },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
Campofinale/Packets/Cs/HandleCsFlushSync.cs
Normal file
35
Campofinale/Packets/Cs/HandleCsFlushSync.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsFlushSync
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsFlushSync)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsFlushSync req = packet.DecodeBody<CsFlushSync>();
|
||||||
|
long curtimestamp = DateTime.UtcNow.ToUnixTimestampMilliseconds();
|
||||||
|
ScFlushSync sync = new()
|
||||||
|
{
|
||||||
|
ClientTs=req.ClientTs,
|
||||||
|
ServerTs=(ulong)curtimestamp,
|
||||||
|
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScFlushSync, sync,packet.csHead.UpSeqid);
|
||||||
|
|
||||||
|
//Logger.Print("Server: " + curtimestamp + " client: " + req.ClientTs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
138
Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs
Normal file
138
Campofinale/Packets/Cs/HandleCsGachaTenPullReq.cs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using Google.Protobuf.WellKnownTypes;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsGachaTenPullReq
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsGachaSinglePullReq)]
|
||||||
|
public static void HandleOnePull(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsGachaSinglePullReq req = packet.DecodeBody<CsGachaSinglePullReq>();
|
||||||
|
session.gachaManager.upSeqId = packet.csHead.UpSeqid;
|
||||||
|
session.gachaManager.DoGacha(req.GachaPoolId, 1);
|
||||||
|
}
|
||||||
|
[Server.Handler(CsMsgId.CsGachaTenPullReq)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsGachaTenPullReq req = packet.DecodeBody<CsGachaTenPullReq>();
|
||||||
|
session.gachaManager.upSeqId = packet.csHead.UpSeqid;
|
||||||
|
session.gachaManager.DoGacha(req.GachaPoolId, 10);
|
||||||
|
/* Random rng = new Random();
|
||||||
|
List<string> chars = new List<string>();
|
||||||
|
const double prob6Star = 0.008; // 0.8%
|
||||||
|
const double prob5Star = 0.08; // 8%
|
||||||
|
const double fiftyfifty = 0.50; // 50%
|
||||||
|
GachaCharPoolTable table = ResourceManager.gachaCharPoolTable[req.GachaPoolId];
|
||||||
|
GachaCharPoolContentTable content = ResourceManager.gachaCharPoolContentTable[req.GachaPoolId];
|
||||||
|
int sixstarcount = 0;
|
||||||
|
int fivestarcount = 0;
|
||||||
|
List<GachaCharPoolItem> fiveStars = content.list.FindAll(c => c.starLevel == 5);
|
||||||
|
List<GachaCharPoolItem> sixStars = content.list.FindAll(c => c.starLevel == 6);
|
||||||
|
int fiveStarGuaranteedIndex = new Random().Next(9);
|
||||||
|
for (int i=0; i < 10; i++)
|
||||||
|
{
|
||||||
|
double roll = rng.NextDouble();
|
||||||
|
double fifty = rng.NextDouble();
|
||||||
|
|
||||||
|
if (roll < prob6Star)
|
||||||
|
{
|
||||||
|
sixstarcount++;
|
||||||
|
|
||||||
|
if (table.upCharIds.Count > 0)
|
||||||
|
{
|
||||||
|
if (fifty >= fiftyfifty)
|
||||||
|
{
|
||||||
|
chars.Add(ResourceManager.characterTable[table.upCharIds[0]].charId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars.Add(sixStars[new Random().Next(sixStars.Count - 1)].charId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars.Add(sixStars[new Random().Next(sixStars.Count - 1)].charId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (roll < prob6Star + prob5Star || fiveStarGuaranteedIndex == i)
|
||||||
|
{
|
||||||
|
fivestarcount++;
|
||||||
|
if(table.upCharIds.Count > 1)
|
||||||
|
{
|
||||||
|
if(fifty >= fiftyfifty)
|
||||||
|
{
|
||||||
|
chars.Add(ResourceManager.characterTable[table.upCharIds[1]].charId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars.Add(fiveStars[new Random().Next(fiveStars.Count - 1)].charId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars.Add(fiveStars[new Random().Next(fiveStars.Count-1)].charId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chars.Add(ResourceManager.characterTable.Values.ToList().FindAll(c=>c.rarity == 4)[new Random().Next(ResourceManager.characterTable.Values.ToList().FindAll(c => c.rarity == 4).Count - 1)].charId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
ScGachaSyncPullResult result = new ScGachaSyncPullResult()
|
||||||
|
{
|
||||||
|
GachaPoolId=req.GachaPoolId,
|
||||||
|
GachaType=req.GachaType,
|
||||||
|
|
||||||
|
OriResultIds =
|
||||||
|
{
|
||||||
|
},
|
||||||
|
Star5GotCount= fivestarcount,
|
||||||
|
Star6GotCount= sixstarcount,
|
||||||
|
FinalResults =
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
UpGotCount= fivestarcount+ sixstarcount,
|
||||||
|
|
||||||
|
};
|
||||||
|
foreach(string ch in chars)
|
||||||
|
{
|
||||||
|
bool exist = session.chars.Find(c => c.id == ch) != null;
|
||||||
|
result.OriResultIds.Add(ch);
|
||||||
|
result.FinalResults.Add(new ScdGachaFinalResult()
|
||||||
|
{
|
||||||
|
IsNew= !exist,
|
||||||
|
ItemId=ch,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//session.Send(Packet.EncodePacket((int)CsMessageId.CsGachaTenPullReq, req));
|
||||||
|
|
||||||
|
session.Send(ScMessageId.ScGachaSyncPullResult, result); */
|
||||||
|
// session.Send(CsMessageId.CsGachaEnd, new Empty());
|
||||||
|
// session.Send(ScMessageId.ScGachaBegin, new Empty());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
Campofinale/Packets/Cs/HandleCsGetMail.cs
Normal file
19
Campofinale/Packets/Cs/HandleCsGetMail.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsGetMail
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsGetMail)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsGetMail req = packet.DecodeBody<CsGetMail>();
|
||||||
|
session.Send(new PacketScGetMail(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
28
Campofinale/Packets/Cs/HandleCsLeaveDungeon.cs
Normal file
28
Campofinale/Packets/Cs/HandleCsLeaveDungeon.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsLeaveDungeon
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsLeaveDungeon)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsLeaveDungeon req = packet.DecodeBody<CsLeaveDungeon>();
|
||||||
|
|
||||||
|
session.LeaveDungeon(req);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
269
Campofinale/Packets/Cs/HandleCsLogin.cs
Normal file
269
Campofinale/Packets/Cs/HandleCsLogin.cs
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
using BeyondTools.VFS.Crypto;
|
||||||
|
using Campofinale.Database;
|
||||||
|
using Campofinale.Game;
|
||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Packets.Sc;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Campofinale.Resource;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using static Campofinale.Resource.ResourceManager;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsLogin
|
||||||
|
{
|
||||||
|
[Server.Handler(CsMsgId.CsCreateRole)]
|
||||||
|
public static void HandleCsCreateRole(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsCreateRole req = packet.DecodeBody<CsCreateRole>();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
[Server.Handler(CsMsgId.CsLogin)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet packet)
|
||||||
|
{
|
||||||
|
CsLogin req = packet.DecodeBody<CsLogin>();
|
||||||
|
if(Server.clients.Count > Server.config.serverOptions.maxPlayers)
|
||||||
|
{
|
||||||
|
session.Send(ScMsgId.ScNtfErrorCode, new ScNtfErrorCode()
|
||||||
|
{
|
||||||
|
Details = "Server Full",
|
||||||
|
ErrorCode = (int)CODE.ErrCommonServerOverload,
|
||||||
|
});
|
||||||
|
session.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Account account = DatabaseManager.db.GetAccountByTokenGrant(req.Token);
|
||||||
|
ScLogin rsp = new()
|
||||||
|
{
|
||||||
|
IsEnc = false,
|
||||||
|
Uid = req.Uid,
|
||||||
|
IsFirstLogin = false,
|
||||||
|
IsReconnect=false,
|
||||||
|
LastRecvUpSeqid = packet.csHead.UpSeqid,
|
||||||
|
|
||||||
|
};
|
||||||
|
byte[] encKey = GenerateRandomBytes(32);
|
||||||
|
string serverPublicKeyPem = req.ClientPublicKey.ToStringUtf8();
|
||||||
|
byte[] serverPublicKey = ConvertPemToBytes(serverPublicKeyPem);
|
||||||
|
byte[] encryptedEncKey = EncryptWithRsa(encKey, serverPublicKey);
|
||||||
|
byte[] serverEncrypNonce = GenerateRandomBytes(12);
|
||||||
|
// rsp.ServerEncrypNonce = ByteString.CopyFrom(serverEncrypNonce);
|
||||||
|
// rsp.ServerPublicKey = ByteString.CopyFrom(encryptedEncKey);
|
||||||
|
|
||||||
|
CSChaCha20 cipher = new CSChaCha20(encKey, serverEncrypNonce, 1);
|
||||||
|
if (req.ClientVersion == GameConstants.GAME_VERSION)
|
||||||
|
{
|
||||||
|
if (account == null)
|
||||||
|
{
|
||||||
|
session.Send(ScMsgId.ScNtfErrorCode, new ScNtfErrorCode()
|
||||||
|
{
|
||||||
|
Details = "Account error",
|
||||||
|
ErrorCode = (int)CODE.ErrLoginProcessLogin,
|
||||||
|
});
|
||||||
|
session.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
session.Load(account.id);
|
||||||
|
|
||||||
|
rsp.Uid = ""+session.accountId;
|
||||||
|
session.Send(ScMsgId.ScLogin, rsp);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
session.Send(ScMsgId.ScNtfErrorCode, new ScNtfErrorCode()
|
||||||
|
{
|
||||||
|
Details="Unsupported client version",
|
||||||
|
ErrorCode= (int)CODE.ErrCommonClientVersionNotEqual
|
||||||
|
});
|
||||||
|
session.Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
session.Send(new PacketScSyncBaseData(session));
|
||||||
|
ScItemBagCommonSync common = new()
|
||||||
|
{
|
||||||
|
LostAndFound = new()
|
||||||
|
{
|
||||||
|
InstList =
|
||||||
|
{
|
||||||
|
new ScdItemGrid()
|
||||||
|
{
|
||||||
|
GridIndex=0,
|
||||||
|
Count=1,
|
||||||
|
Id="item_port_power_pole_2",
|
||||||
|
Inst = new()
|
||||||
|
{
|
||||||
|
InstId=300000000000,
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
session.Send(ScMsgId.ScItemBagCommonSync, common);
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Weapon));
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.WeaponGem));
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Equip));
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.CommercialItem));
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.Factory));
|
||||||
|
session.Send(new PacketScItemBagScopeSync(session, ItemValuableDepotType.SpecialItem));
|
||||||
|
session.Send(new PacketScSyncAllMail(session));
|
||||||
|
session.Send(new PacketScSceneCollectionSync(session));
|
||||||
|
/*ScSyncAllMission missions = new()
|
||||||
|
{
|
||||||
|
Missions =
|
||||||
|
{
|
||||||
|
{"e0m0",
|
||||||
|
new Mission()
|
||||||
|
{
|
||||||
|
MissionId="e0m0",
|
||||||
|
MissionState=(int)MissionState.Processing,
|
||||||
|
Properties =
|
||||||
|
{
|
||||||
|
{1,new DynamicParameter()
|
||||||
|
{
|
||||||
|
ValueType=1,
|
||||||
|
RealType=1,
|
||||||
|
ValueBoolList =
|
||||||
|
{
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{2,new DynamicParameter()
|
||||||
|
{
|
||||||
|
ValueType=1,
|
||||||
|
RealType=1,
|
||||||
|
ValueBoolList =
|
||||||
|
{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{3,new DynamicParameter()
|
||||||
|
{
|
||||||
|
ValueType=1,
|
||||||
|
RealType=1,
|
||||||
|
ValueBoolList =
|
||||||
|
{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TrackMissionId= "e0m0",
|
||||||
|
CurQuests =
|
||||||
|
{
|
||||||
|
{"e0m0#1", new Quest(){
|
||||||
|
QuestId="e0m0#1",
|
||||||
|
QuestState=2,
|
||||||
|
QuestObjectives =
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
};*/
|
||||||
|
//session.Send(ScMessageId.ScSyncAllMission, missions);
|
||||||
|
string json1 = File.ReadAllText("44_ScSyncAllMission.json");
|
||||||
|
ScSyncAllMission m = Newtonsoft.Json.JsonConvert.DeserializeObject<ScSyncAllMission>(json1);
|
||||||
|
m.TrackMissionId = "";
|
||||||
|
session.Send(ScMsgId.ScSyncAllMission, m);
|
||||||
|
|
||||||
|
|
||||||
|
session.Send(new PacketScGachaSync(session));
|
||||||
|
ScSettlementSyncAll settlements = new ScSettlementSyncAll()
|
||||||
|
{
|
||||||
|
LastTickTime = DateTime.UtcNow.ToUnixTimestampMilliseconds(),
|
||||||
|
|
||||||
|
};
|
||||||
|
int stid = 3;
|
||||||
|
foreach (var item in settlementBasicDataTable)
|
||||||
|
{
|
||||||
|
settlements.Settlements.Add(new Settlement()
|
||||||
|
{
|
||||||
|
Level = 1,
|
||||||
|
SettlementId = item.Value.settlementId,
|
||||||
|
RequireId = "item_plant_grass_powder_2",
|
||||||
|
Exp = 1,
|
||||||
|
Reports =
|
||||||
|
{
|
||||||
|
|
||||||
|
},
|
||||||
|
UnlockTs = DateTime.UtcNow.AddHours(1).ToUnixTimestampMilliseconds(),
|
||||||
|
AutoSubmit = false,
|
||||||
|
LastManualSubmitTime = DateTime.UtcNow.ToUnixTimestampMilliseconds(),
|
||||||
|
|
||||||
|
OfficerCharTemplateId = characterTable.Values.ToList()[stid].charId,
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
stid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.Send(ScMsgId.ScSettlementSyncAll, settlements);
|
||||||
|
session.Send(new PacketScSyncAllRoleScene(session));
|
||||||
|
session.Send(new PacketScGameMechanicsSync(session));
|
||||||
|
session.Send(new PacketScSyncAllBloc(session));
|
||||||
|
session.Send(new PacketScSyncWallet(session));
|
||||||
|
session.Send(new PacketScSyncAllGameVar(session));
|
||||||
|
session.Send(new PacketScSyncAllUnlock(session));
|
||||||
|
session.Send(new PacketScSyncAllBitset(session));
|
||||||
|
session.Send(new PacketScSyncAllMiniGame(session));
|
||||||
|
|
||||||
|
string json = File.ReadAllText("93_ScSceneMapMarkSync.json");
|
||||||
|
ScSceneMapMarkSync chapter = Newtonsoft.Json.JsonConvert.DeserializeObject<ScSceneMapMarkSync>(json);
|
||||||
|
session.Send(ScMsgId.ScSceneMapMarkSync, chapter);
|
||||||
|
session.Send(new PacketScAdventureBookSync(session));
|
||||||
|
session.Send(new PacketScAdventureSyncAll(session));
|
||||||
|
session.Send(new PacketScFactorySync(session));
|
||||||
|
session.Send(new PacketScFactorySyncScope(session));
|
||||||
|
session.Send(new PacketScFactorySyncChapter(session, "domain_1"));
|
||||||
|
session.Send(new PacketScFactorySyncChapter(session, "domain_2"));
|
||||||
|
session.Send(new PacketScSyncCharBagInfo(session));
|
||||||
|
session.Send(new PacketScSyncAllDialog(session));
|
||||||
|
session.Send(new PacketScSpaceshipSync(session));
|
||||||
|
session.Send(new PacketScSyncFullDungeonStatus(session));
|
||||||
|
session.Send(new PacketScActivitySync(session));
|
||||||
|
|
||||||
|
session.Send(ScMsgId.ScSyncFullDataEnd, new ScSyncFullDataEnd());
|
||||||
|
session.EnterScene();
|
||||||
|
session.Initialized = true;
|
||||||
|
session.Update();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
static byte[] GenerateRandomBytes(int length)
|
||||||
|
{
|
||||||
|
using var rng = new RNGCryptoServiceProvider();
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
rng.GetBytes(bytes);
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
static byte[] ConvertPemToBytes(string pem)
|
||||||
|
{
|
||||||
|
string base64Key = pem
|
||||||
|
.Replace("-----BEGIN PUBLIC KEY-----", "")
|
||||||
|
.Replace("-----END PUBLIC KEY-----", "")
|
||||||
|
.Replace("\n", "")
|
||||||
|
.Replace("\r", "");
|
||||||
|
return Convert.FromBase64String(base64Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crittografare con RSA (PKCS#1)
|
||||||
|
static byte[] EncryptWithRsa(byte[] data, byte[] publicKeyBytes)
|
||||||
|
{
|
||||||
|
var rsa = RSA.Create();
|
||||||
|
rsa.ImportSubjectPublicKeyInfo(publicKeyBytes, out _);
|
||||||
|
return rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
60
Campofinale/Packets/Cs/HandleCsMergeMsg.cs
Normal file
60
Campofinale/Packets/Cs/HandleCsMergeMsg.cs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
using Campofinale.Network;
|
||||||
|
using Campofinale.Protocol;
|
||||||
|
using Google.Protobuf;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace Campofinale.Packets.Cs
|
||||||
|
{
|
||||||
|
public class HandleCsMergeMsg
|
||||||
|
{
|
||||||
|
|
||||||
|
[Server.Handler(CsMsgId.CsMergeMsg)]
|
||||||
|
public static void Handle(Player session, CsMsgId cmdId, Packet p)
|
||||||
|
{
|
||||||
|
CsMergeMsg req = p.DecodeBody<CsMergeMsg>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
byte[] allBytes = req.Msg.ToByteArray();
|
||||||
|
while (allBytes.Length > 3) {
|
||||||
|
|
||||||
|
byte headLength = Packet.GetByte(allBytes, 0);
|
||||||
|
ushort bodyLength = Packet.GetUInt16(allBytes, 1);
|
||||||
|
|
||||||
|
byte[] head = allBytes.AsSpan().Slice(3, headLength).ToArray();
|
||||||
|
byte[] body = allBytes.AsSpan().Slice(3+ headLength, bodyLength).ToArray();
|
||||||
|
Packet packet = new()
|
||||||
|
{
|
||||||
|
finishedBody = body,
|
||||||
|
csHead = CSHead.Parser.ParseFrom(head),
|
||||||
|
cmdId = CSHead.Parser.ParseFrom(head).Msgid,
|
||||||
|
|
||||||
|
};
|
||||||
|
if (Server.config.logOptions.packets)
|
||||||
|
{
|
||||||
|
Logger.Print("CmdId: " + (CsMsgId)packet.csHead.Msgid);
|
||||||
|
Logger.Print(BitConverter.ToString(packet.finishedBody).Replace("-", string.Empty).ToLower());
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NotifyManager.Notify(session, (CsMsgId)packet.cmdId, packet);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.PrintError("Error while notify packet: " + e.Message);
|
||||||
|
}
|
||||||
|
allBytes = allBytes.AsSpan().Slice(3 + headLength + bodyLength).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user