关于最近网上谣言传的很凶的 “太吾绘卷” 游戏源代码的问题。

94 篇文章 2 订阅
53 篇文章 2 订阅


    这两天吵的挺厉害的,我本人觉得喜欢这类题材的人们也可以去支持一下这个游戏,但是有一点恶意的抨击别人的代码写得乱,我感到真的没必要,先想想你自己写的怎么样再来说吧。

   当然我这不是为 “太吾绘卷” 洗白,这跟我没关系(不是一起的),但是我说过我很厌恶装逼侠,它们都令我都有一点点语言歧视,我可以说我把 “太吾绘卷” 的 .net dlllib 提取出来了(相当于代码出来了)但是本人想说,虽然 “太吾” 的代码写得很一般,一些地方有不少设计不合理的地方、有些地方的耦合冗余继承及嵌套深度的确比是较大,当然这个在不同项目里面都无法避免,只能说会逐步的进行修复代码重构调整,另外你们知道是什么是按具体场景下菜?是不是在你们的眼中不用洋葱六边形就等于很差?遇到你们看不懂的模式也等于乱?所有的东西一定要整最复杂的架构最复杂的写法最没有效率的写法才是对的?搞笑,有的时候该拷贝代码的就的拷贝代码,知道为什么?好好去想想再来回答这个问题,不要又给我一个标准答案是为了 “码的快” ~这样只会让我压不住我的笑意~,另外代码也不至于被网路上疯传说的那么差劲,我觉得我们是不是应该尊重一个客观的事实。

   国内能把代码到一般水平的人也需要好好码几年沉淀一下,追求代码 “行云流水”、“一气呵成” 那是玩代码艺术(质量 >= 90分,>= 95分很难写,一行代码扣脑袋得扣半天),都是一帮牛魔王的人才写的出来,一般人想想就好了,

  当然本人贴出的一部分东西,真伪你们可以找 “太吾绘卷”  的技术团队论证代码的真伪,我觉得这个没有什么好装逼的,虽然搞掉这个东西也没花到太久的时间,但是这也说明了 “太吾绘卷” 在这块做的安全性不是很好,当然提高安全的办法有不少,但这不是我在本人要谈到的,我说过跟我一点关系没有。本人只是单纯的看不惯装逼犯,要装逼去 java 那边去,你们一起装,可劲的装不要停,停了是罪,停了是恶!

  另外本人不会提供代码,也不会破解这个游戏,它跟我没有任何冲突,另外我本人实在找不到破解这游戏的一个理由在哪里,秀技术?算了这东西又不难,对于比我 “高或同层次” 的工程师来说,我这可能是要自己打自己的打脸的节奏~呀(装逼,秀技术不是这么秀的);第二我现在一直又氪又肝 “楚留香” 这个游戏,第三我现在是混 “医疗千秋行业” 的。。。当然玩一个几十块钱的单机还想着破解,弄外挂,你们真的也是够了,有啥意思,除了自慰。。。(发自肺腑)。。。

   

  上面用C/C++写的代码是用于从加密的 “伪dll” 中提取真正的 “.net dlllib”,u3d-csharp 是基于 mono 的体系,而 mono 只支持到 .net 3.5(所以这个dll 工程师是 .net 2.0 的也不足为奇)当然你可以利用 mono 对你 .net dlllib 加密,但是这个东西真的很脆弱,虽然它在不同版本中可能会不一致,但是大体函数的签名是没有变的,破掉的方法有几种,一种是调用 XXX【打黑码,本人不是教你们来玩破解的】 库加载到进程的模块空间,然后在把它 dump 出来(无论你是通过emit组建,还是直接从模块表中提出)还有就是破解密函数(这个比较省事,需要分析写的代码都会少很多),.... ,另外我想,你们能把 mono 内链静态编译的话,几乎就把目前 99% 人砍掉,剩下这批也没多大心情会去搞你这个玩意,浪费的时间与回报简直不成正比,当然办法还有很多增加别人成本,到它不能忍受你就赢了,要想根治是不可能的。。。

   本人随便从 “太吾绘卷” 中摘要一些代码吧,它们喷别人的代码中带有 “MonoBehaviour” 我就贴几个与此相关的代码,各位看官自行判断吧。

SystemSetting:(这是临时补上的一部分,系统设置选项卡的部分,其它的肯定不会提出来这部分代码少,同时并不是很重要对太吾来说影响不大)

// SystemSetting
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class SystemSetting : MonoBehaviour
{
	public static SystemSetting instance;

	public GameObject SystemSettingWindow;

	public Text[] windowText;

	public Dropdown setResolution;

	public Toggle setFullScreen;

	public GameObject exitButton;

	public Slider BGMVolumeSlider;

	public Slider SEVolumeSlider;

	public Toggle BGMOffToggle;

	public Toggle SEOffToggle;

	public Text BGMVolumeText;

	public Text SEVolumeText;

	public Toggle DamageValueToggle;

	public Toggle DamagePartToggle;

	public Toggle ShowTaiwuToggle;

	public Toggle HeidTaiwuToggle;

	private Resolution[] resolutions;

	public void ShowSystemSettingWindow(bool showExit)
	{
		exitButton.SetActive(showExit);
		SystemSettingWindow.SetActive(true);
	}

	public void CloseSettingWindow()
	{
		SystemSettingWindow.SetActive(false);
		SaveDateFile.instance.SaveSystemSetting();
	}

	public void BackToStartMenu()
	{
		CloseSettingWindow();
		YesOrNoWindow.instance.SetYesOrNoWindow(306, DateFile.instance.massageDate[701][0], DateFile.instance.massageDate[701][2], false, true);
	}

	public void SetBGMVolume()
	{
		DateFile.instance.SetBGMVolume(BGMVolumeSlider.value);
		UpdateBGMVolumeText();
	}

	public void SetSEVolume()
	{
		DateFile.instance.SetSEVolume(SEVolumeSlider.value);
		UpdateSEVolumeText();
	}

	public void SetBGMOff()
	{
		DateFile.instance.SetBGMOff(BGMOffToggle.isOn);
		BGMVolumeSlider.interactable = !DateFile.instance.BGMOff;
		UpdateBGMVolumeText();
	}

	public void SetSEOff()
	{
		DateFile.instance.SetSEOff(SEOffToggle.isOn);
		SEVolumeSlider.interactable = !DateFile.instance.SEOff;
		UpdateSEVolumeText();
	}

	public void SetFullScreen()
	{
		DateFile.instance.SetFullScreen(setFullScreen.isOn);
	}

	private void UpdateBGMVolumeText()
	{
		BGMVolumeText.text = ((!DateFile.instance.BGMOff) ? (Convert.ToInt32(DateFile.instance.BGMVolume * 100f) + "%") : "0%");
	}

	private void UpdateSEVolumeText()
	{
		SEVolumeText.text = ((!DateFile.instance.SEOff) ? (Convert.ToInt32(DateFile.instance.SEVolume * 100f) + "%") : "0%");
	}

	private void Awake()
	{
		instance = this;
	}

	private void Start()
	{
		resolutions = Screen.resolutions;
		setResolution.ClearOptions();
		DateFile.instance.gameResolutions = new List<Resolution>();
		for (int i = 0; i < resolutions.Length; i++)
		{
			int width = resolutions[i].width;
			int height = resolutions[i].height;
			if (width * 100 / height > 160)
			{
				DateFile.instance.gameResolutions.Add(resolutions[i]);
				setResolution.options.Add(new Dropdown.OptionData
				{
					text = string.Format("{0} × {1}", width, height)
				});
			}
		}
		setResolution.onValueChanged.AddListener(DateFile.instance.SetScreenResolution);
		setResolution.captionText.text = string.Format("{0} × {1}", DateFile.instance.screenWidth, DateFile.instance.screenheight);
		setFullScreen.isOn = DateFile.instance.fullScreen;
		setFullScreen.onValueChanged.AddListener(DateFile.instance.SetFullScreen);
		if (DateFile.instance.showDamage)
		{
			DamagePartToggle.isOn = false;
			DamageValueToggle.isOn = true;
		}
		else
		{
			DamageValueToggle.isOn = false;
			DamagePartToggle.isOn = true;
		}
		if (DateFile.instance.showTaiwuName)
		{
			ShowTaiwuToggle.isOn = true;
			HeidTaiwuToggle.isOn = false;
		}
		else
		{
			ShowTaiwuToggle.isOn = false;
			HeidTaiwuToggle.isOn = true;
		}
		BGMVolumeSlider.value = DateFile.instance.BGMVolume * 10f;
		SEVolumeSlider.value = DateFile.instance.SEVolume * 10f;
		BGMOffToggle.isOn = DateFile.instance.BGMOff;
		SEOffToggle.isOn = DateFile.instance.SEOff;
		BGMVolumeSlider.interactable = !DateFile.instance.BGMOff;
		SEVolumeSlider.interactable = !DateFile.instance.SEOff;
		UpdateBGMVolumeText();
		UpdateSEVolumeText();
		SystemSettingWindow.transform.localPosition = new Vector3(0f, 0f, 0f);
		SystemSettingWindow.SetActive(false);
		for (int j = 0; j < windowText.Length; j++)
		{
			windowText[j].text = DateFile.instance.massageDate[14][2].Split('|')[j];
		}
	}
}

BoneFollower:

// Spine.Unity.BoneFollower
using Spine;
using Spine.Unity;
using System;
using UnityEngine;
using UnityEngine.Serialization;

[ExecuteInEditMode]
[AddComponentMenu("Spine/BoneFollower")]
public class BoneFollower : MonoBehaviour
{
	public SkeletonRenderer skeletonRenderer;

	[SpineBone("", "skeletonRenderer", true, false)]
	[SerializeField]
	public string boneName;

	public bool followZPosition = true;

	public bool followBoneRotation = true;

	[Tooltip("Follows the skeleton's flip state by controlling this Transform's local scale.")]
	public bool followSkeletonFlip = true;

	[Tooltip("Follows the target bone's local scale. BoneFollower cannot inherit world/skewed scale because of UnityEngine.Transform property limitations.")]
	public bool followLocalScale = false;

	[FormerlySerializedAs("resetOnAwake")]
	public bool initializeOnAwake = true;

	[NonSerialized]
	public bool valid;

	[NonSerialized]
	public Bone bone;

	private Transform skeletonTransform;

	private bool skeletonTransformIsParent;

	public SkeletonRenderer SkeletonRenderer
	{
		get
		{
			return skeletonRenderer;
		}
		set
		{
			skeletonRenderer = value;
			Initialize();
		}
	}

	public bool SetBone(string name)
	{
		bone = skeletonRenderer.skeleton.FindBone(name);
		if (bone != null)
		{
			boneName = name;
			return true;
		}
		Debug.LogError("Bone not found: " + name, this);
		return false;
	}

	public void Awake()
	{
		if (initializeOnAwake)
		{
			Initialize();
		}
	}

	public void HandleRebuildRenderer(SkeletonRenderer skeletonRenderer)
	{
		Initialize();
	}

	public void Initialize()
	{
		bone = null;
		valid = ((UnityEngine.Object)skeletonRenderer != (UnityEngine.Object)null && skeletonRenderer.valid);
		if (valid)
		{
			skeletonTransform = skeletonRenderer.transform;
			skeletonRenderer.OnRebuild -= HandleRebuildRenderer;
			skeletonRenderer.OnRebuild += HandleRebuildRenderer;
			skeletonTransformIsParent = object.ReferenceEquals(skeletonTransform, base.transform.parent);
			if (!string.IsNullOrEmpty(boneName))
			{
				bone = skeletonRenderer.skeleton.FindBone(boneName);
			}
		}
	}

	private void OnDestroy()
	{
		if ((UnityEngine.Object)skeletonRenderer != (UnityEngine.Object)null)
		{
			skeletonRenderer.OnRebuild -= HandleRebuildRenderer;
		}
	}

	public void LateUpdate()
	{
		if (!valid)
		{
			Initialize();
		}
		else
		{
			if (bone == null)
			{
				if (string.IsNullOrEmpty(boneName))
				{
					return;
				}
				bone = skeletonRenderer.skeleton.FindBone(boneName);
				if (!SetBone(boneName))
				{
					return;
				}
			}
			Transform transform = base.transform;
			Quaternion quaternion;
			if (skeletonTransformIsParent)
			{
				Transform transform2 = transform;
				float worldX = bone.worldX;
				float worldY = bone.worldY;
				float z;
				if (followZPosition)
				{
					z = 0f;
				}
				else
				{
					Vector3 localPosition = transform.localPosition;
					z = localPosition.z;
				}
				transform2.localPosition = new Vector3(worldX, worldY, z);
				if (followBoneRotation)
				{
					float num = Mathf.Atan2(bone.c, bone.a) * 0.5f;
					if (followLocalScale && bone.scaleX < 0f)
					{
						num += 1.57079637f;
					}
					quaternion = default(Quaternion);
					Quaternion localRotation = quaternion;
					localRotation.z = Mathf.Sin(num);
					localRotation.w = Mathf.Cos(num);
					transform.localRotation = localRotation;
				}
			}
			else
			{
				Vector3 position = skeletonTransform.TransformPoint(new Vector3(bone.worldX, bone.worldY, 0f));
				if (!followZPosition)
				{
					Vector3 position2 = transform.position;
					position.z = position2.z;
				}
				float num2 = bone.WorldRotationX;
				Transform parent = transform.parent;
				if ((UnityEngine.Object)parent != (UnityEngine.Object)null)
				{
					Matrix4x4 localToWorldMatrix = parent.localToWorldMatrix;
					if (localToWorldMatrix.m00 * localToWorldMatrix.m11 - localToWorldMatrix.m01 * localToWorldMatrix.m10 < 0f)
					{
						num2 = 0f - num2;
					}
				}
				if (followBoneRotation)
				{
					quaternion = skeletonTransform.rotation;
					Vector3 eulerAngles = quaternion.eulerAngles;
					if (followLocalScale && bone.scaleX < 0f)
					{
						num2 += 180f;
					}
					transform.SetPositionAndRotation(position, Quaternion.Euler(eulerAngles.x, eulerAngles.y, eulerAngles.z + num2));
				}
				else
				{
					transform.position = position;
				}
			}
			Vector3 localScale = (!followLocalScale) ? new Vector3(1f, 1f, 1f) : new Vector3(bone.scaleX, bone.scaleY, 1f);
			if (followSkeletonFlip)
			{
				localScale.y *= ((!(bone.skeleton.flipX ^ bone.skeleton.flipY)) ? 1f : (-1f));
			}
			transform.localScale = localScale;
		}
	}
}

SkeletonUtility:

// Spine.Unity.SkeletonUtility
using Spine;
using Spine.Unity;
using System;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(ISkeletonAnimation))]
[ExecuteInEditMode]
public class SkeletonUtility : MonoBehaviour
{
	public delegate void SkeletonUtilityDelegate();

	public Transform boneRoot;

	[HideInInspector]
	public SkeletonRenderer skeletonRenderer;

	[HideInInspector]
	public ISkeletonAnimation skeletonAnimation;

	[NonSerialized]
	public List<SkeletonUtilityBone> utilityBones = new List<SkeletonUtilityBone>();

	[NonSerialized]
	public List<SkeletonUtilityConstraint> utilityConstraints = new List<SkeletonUtilityConstraint>();

	protected bool hasTransformBones;

	protected bool hasUtilityConstraints;

	protected bool needToReprocessBones;

	public event SkeletonUtilityDelegate OnReset;

	public static PolygonCollider2D AddBoundingBoxGameObject(Skeleton skeleton, string skinName, string slotName, string attachmentName, Transform parent, bool isTrigger = true)
	{
		Skin skin = (!string.IsNullOrEmpty(skinName)) ? skeleton.data.FindSkin(skinName) : skeleton.data.defaultSkin;
		if (skin != null)
		{
			Attachment attachment = skin.GetAttachment(skeleton.FindSlotIndex(slotName), attachmentName);
			if (attachment != null)
			{
				BoundingBoxAttachment boundingBoxAttachment = attachment as BoundingBoxAttachment;
				if (boundingBoxAttachment == null)
				{
					Debug.LogFormat("Attachment '{0}' was not a Bounding Box.", attachmentName);
					return null;
				}
				Slot slot = skeleton.FindSlot(slotName);
				return AddBoundingBoxGameObject(boundingBoxAttachment.Name, boundingBoxAttachment, slot, parent, isTrigger);
			}
			Debug.LogFormat("Attachment in slot '{0}' named '{1}' not found in skin '{2}'.", slotName, attachmentName, skin.name);
			return null;
		}
		Debug.LogError("Skin " + skinName + " not found!");
		return null;
	}

	public static PolygonCollider2D AddBoundingBoxGameObject(string name, BoundingBoxAttachment box, Slot slot, Transform parent, bool isTrigger = true)
	{
		GameObject gameObject = new GameObject("[BoundingBox]" + ((!string.IsNullOrEmpty(name)) ? name : box.Name));
		Transform transform = gameObject.transform;
		transform.parent = parent;
		transform.localPosition = Vector3.zero;
		transform.localRotation = Quaternion.identity;
		transform.localScale = Vector3.one;
		return AddBoundingBoxAsComponent(box, slot, gameObject, isTrigger, true, 0f);
	}

	public static PolygonCollider2D AddBoundingBoxAsComponent(BoundingBoxAttachment box, Slot slot, GameObject gameObject, bool isTrigger = true, bool isKinematic = true, float gravityScale = 0f)
	{
		if (box != null)
		{
			if (slot.bone != slot.Skeleton.RootBone)
			{
				Rigidbody2D component = gameObject.GetComponent<Rigidbody2D>();
				if ((UnityEngine.Object)component == (UnityEngine.Object)null)
				{
					component = gameObject.AddComponent<Rigidbody2D>();
					component.isKinematic = isKinematic;
					component.gravityScale = gravityScale;
				}
			}
			PolygonCollider2D polygonCollider2D = gameObject.AddComponent<PolygonCollider2D>();
			polygonCollider2D.isTrigger = isTrigger;
			SetColliderPointsLocal(polygonCollider2D, slot, box);
			return polygonCollider2D;
		}
		return null;
	}

	public static void SetColliderPointsLocal(PolygonCollider2D collider, Slot slot, BoundingBoxAttachment box)
	{
		if (box != null)
		{
			if (box.IsWeighted())
			{
				Debug.LogWarning("UnityEngine.PolygonCollider2D does not support weighted or animated points. Collider points will not be animated and may have incorrect orientation. If you want to use it as a collider, please remove weights and animations from the bounding box in Spine editor.");
			}
			Vector2[] localVertices = box.GetLocalVertices(slot, null);
			collider.SetPath(0, localVertices);
		}
	}

	public static Bounds GetBoundingBoxBounds(BoundingBoxAttachment boundingBox, float depth = 0f)
	{
		float[] vertices = boundingBox.Vertices;
		int num = vertices.Length;
		Bounds result = default(Bounds);
		result.center = new Vector3(vertices[0], vertices[1], 0f);
		for (int i = 2; i < num; i += 2)
		{
			result.Encapsulate(new Vector3(vertices[i], vertices[i + 1], 0f));
		}
		Vector3 size = result.size;
		size.z = depth;
		result.size = size;
		return result;
	}

	private void Update()
	{
		Skeleton skeleton = skeletonRenderer.skeleton;
		if ((UnityEngine.Object)boneRoot != (UnityEngine.Object)null && skeleton != null)
		{
			Vector3 one = Vector3.one;
			if (skeleton.FlipX)
			{
				one.x = -1f;
			}
			if (skeleton.FlipY)
			{
				one.y = -1f;
			}
			boneRoot.localScale = one;
		}
	}

	private void OnEnable()
	{
		if ((UnityEngine.Object)skeletonRenderer == (UnityEngine.Object)null)
		{
			skeletonRenderer = GetComponent<SkeletonRenderer>();
		}
		if (skeletonAnimation == null)
		{
			skeletonAnimation = GetComponent<SkeletonAnimation>();
			if (skeletonAnimation == null)
			{
				skeletonAnimation = GetComponent<SkeletonAnimator>();
			}
		}
		skeletonRenderer.OnRebuild -= HandleRendererReset;
		skeletonRenderer.OnRebuild += HandleRendererReset;
		if (skeletonAnimation != null)
		{
			skeletonAnimation.UpdateLocal -= UpdateLocal;
			skeletonAnimation.UpdateLocal += UpdateLocal;
		}
		CollectBones();
	}

	private void Start()
	{
		CollectBones();
	}

	private void OnDisable()
	{
		skeletonRenderer.OnRebuild -= HandleRendererReset;
		if (skeletonAnimation != null)
		{
			skeletonAnimation.UpdateLocal -= UpdateLocal;
			skeletonAnimation.UpdateWorld -= UpdateWorld;
			skeletonAnimation.UpdateComplete -= UpdateComplete;
		}
	}

	private void HandleRendererReset(SkeletonRenderer r)
	{
		if (this.OnReset != null)
		{
			this.OnReset();
		}
		CollectBones();
	}

	public void RegisterBone(SkeletonUtilityBone bone)
	{
		if (!utilityBones.Contains(bone))
		{
			utilityBones.Add(bone);
			needToReprocessBones = true;
		}
	}

	public void UnregisterBone(SkeletonUtilityBone bone)
	{
		utilityBones.Remove(bone);
	}

	public void RegisterConstraint(SkeletonUtilityConstraint constraint)
	{
		if (!utilityConstraints.Contains(constraint))
		{
			utilityConstraints.Add(constraint);
			needToReprocessBones = true;
		}
	}

	public void UnregisterConstraint(SkeletonUtilityConstraint constraint)
	{
		utilityConstraints.Remove(constraint);
	}

	public void CollectBones()
	{
		Skeleton skeleton = skeletonRenderer.skeleton;
		if (skeleton != null)
		{
			if ((UnityEngine.Object)boneRoot != (UnityEngine.Object)null)
			{
				List<object> list = new List<object>();
				ExposedList<IkConstraint> ikConstraints = skeleton.IkConstraints;
				int i = 0;
				for (int count = ikConstraints.Count; i < count; i++)
				{
					list.Add(ikConstraints.Items[i].target);
				}
				ExposedList<TransformConstraint> transformConstraints = skeleton.TransformConstraints;
				int j = 0;
				for (int count2 = transformConstraints.Count; j < count2; j++)
				{
					list.Add(transformConstraints.Items[j].target);
				}
				List<SkeletonUtilityBone> list2 = utilityBones;
				int k = 0;
				for (int count3 = list2.Count; k < count3; k++)
				{
					SkeletonUtilityBone skeletonUtilityBone = list2[k];
					if (skeletonUtilityBone.bone != null)
					{
						hasTransformBones |= (skeletonUtilityBone.mode == SkeletonUtilityBone.Mode.Override);
						hasUtilityConstraints |= list.Contains(skeletonUtilityBone.bone);
					}
				}
				hasUtilityConstraints |= (utilityConstraints.Count > 0);
				if (skeletonAnimation != null)
				{
					skeletonAnimation.UpdateWorld -= UpdateWorld;
					skeletonAnimation.UpdateComplete -= UpdateComplete;
					if (hasTransformBones || hasUtilityConstraints)
					{
						skeletonAnimation.UpdateWorld += UpdateWorld;
					}
					if (hasUtilityConstraints)
					{
						skeletonAnimation.UpdateComplete += UpdateComplete;
					}
				}
				needToReprocessBones = false;
			}
			else
			{
				utilityBones.Clear();
				utilityConstraints.Clear();
			}
		}
	}

	private void UpdateLocal(ISkeletonAnimation anim)
	{
		if (needToReprocessBones)
		{
			CollectBones();
		}
		List<SkeletonUtilityBone> list = utilityBones;
		if (list != null)
		{
			int i = 0;
			for (int count = list.Count; i < count; i++)
			{
				list[i].transformLerpComplete = false;
			}
			UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Local);
		}
	}

	private void UpdateWorld(ISkeletonAnimation anim)
	{
		UpdateAllBones(SkeletonUtilityBone.UpdatePhase.World);
		int i = 0;
		for (int count = utilityConstraints.Count; i < count; i++)
		{
			utilityConstraints[i].DoUpdate();
		}
	}

	private void UpdateComplete(ISkeletonAnimation anim)
	{
		UpdateAllBones(SkeletonUtilityBone.UpdatePhase.Complete);
	}

	private void UpdateAllBones(SkeletonUtilityBone.UpdatePhase phase)
	{
		if ((UnityEngine.Object)boneRoot == (UnityEngine.Object)null)
		{
			CollectBones();
		}
		List<SkeletonUtilityBone> list = utilityBones;
		if (list != null)
		{
			int i = 0;
			for (int count = list.Count; i < count; i++)
			{
				list[i].DoUpdate(phase);
			}
		}
	}

	public Transform GetBoneRoot()
	{
		if (!((UnityEngine.Object)boneRoot != (UnityEngine.Object)null))
		{
			boneRoot = new GameObject("SkeletonUtility-Root").transform;
			boneRoot.parent = base.transform;
			boneRoot.localPosition = Vector3.zero;
			boneRoot.localRotation = Quaternion.identity;
			boneRoot.localScale = Vector3.one;
			return boneRoot;
		}
		return boneRoot;
	}

	public GameObject SpawnRoot(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca)
	{
		GetBoneRoot();
		Skeleton skeleton = skeletonRenderer.skeleton;
		GameObject result = SpawnBone(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
		CollectBones();
		return result;
	}

	public GameObject SpawnHierarchy(SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca)
	{
		GetBoneRoot();
		Skeleton skeleton = skeletonRenderer.skeleton;
		GameObject result = SpawnBoneRecursively(skeleton.RootBone, boneRoot, mode, pos, rot, sca);
		CollectBones();
		return result;
	}

	public GameObject SpawnBoneRecursively(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca)
	{
		GameObject gameObject = SpawnBone(bone, parent, mode, pos, rot, sca);
		ExposedList<Bone> children = bone.Children;
		int i = 0;
		for (int count = children.Count; i < count; i++)
		{
			Bone bone2 = children.Items[i];
			SpawnBoneRecursively(bone2, gameObject.transform, mode, pos, rot, sca);
		}
		return gameObject;
	}

	public GameObject SpawnBone(Bone bone, Transform parent, SkeletonUtilityBone.Mode mode, bool pos, bool rot, bool sca)
	{
		GameObject gameObject = new GameObject(bone.Data.Name);
		gameObject.transform.parent = parent;
		SkeletonUtilityBone skeletonUtilityBone = gameObject.AddComponent<SkeletonUtilityBone>();
		skeletonUtilityBone.skeletonUtility = this;
		skeletonUtilityBone.position = pos;
		skeletonUtilityBone.rotation = rot;
		skeletonUtilityBone.scale = sca;
		skeletonUtilityBone.mode = mode;
		skeletonUtilityBone.zPosition = true;
		skeletonUtilityBone.Reset();
		skeletonUtilityBone.bone = bone;
		skeletonUtilityBone.boneName = bone.Data.Name;
		skeletonUtilityBone.valid = true;
		if (mode == SkeletonUtilityBone.Mode.Override)
		{
			if (rot)
			{
				gameObject.transform.localRotation = Quaternion.Euler(0f, 0f, skeletonUtilityBone.bone.AppliedRotation);
			}
			if (pos)
			{
				gameObject.transform.localPosition = new Vector3(skeletonUtilityBone.bone.X, skeletonUtilityBone.bone.Y, 0f);
			}
			gameObject.transform.localScale = new Vector3(skeletonUtilityBone.bone.scaleX, skeletonUtilityBone.bone.scaleY, 0f);
		}
		return gameObject;
	}
}

  PointFollower:

// Spine.Unity.PointFollower
using Spine;
using Spine.Unity;
using UnityEngine;

[ExecuteInEditMode]
[AddComponentMenu("Spine/Point Follower")]
public class PointFollower : MonoBehaviour, IHasSkeletonRenderer, IHasSkeletonComponent
{
	[SerializeField]
	public SkeletonRenderer skeletonRenderer;

	[SpineSlot("", "skeletonRenderer", false, true, false)]
	public string slotName;

	[SpineAttachment(true, false, false, "slotName", "skeletonRenderer", "", true, true)]
	public string pointAttachmentName;

	public bool followRotation = true;

	public bool followSkeletonFlip = true;

	public bool followSkeletonZPosition = false;

	private Transform skeletonTransform;

	private bool skeletonTransformIsParent;

	private PointAttachment point;

	private Bone bone;

	private bool valid;

	public SkeletonRenderer SkeletonRenderer
	{
		get
		{
			return skeletonRenderer;
		}
	}

	public ISkeletonComponent SkeletonComponent
	{
		get
		{
			return skeletonRenderer;
		}
	}

	public bool IsValid
	{
		get
		{
			return valid;
		}
	}

	public void Initialize()
	{
		valid = ((Object)skeletonRenderer != (Object)null && skeletonRenderer.valid);
		if (valid)
		{
			UpdateReferences();
		}
	}

	private void HandleRebuildRenderer(SkeletonRenderer skeletonRenderer)
	{
		Initialize();
	}

	private void UpdateReferences()
	{
		skeletonTransform = skeletonRenderer.transform;
		skeletonRenderer.OnRebuild -= HandleRebuildRenderer;
		skeletonRenderer.OnRebuild += HandleRebuildRenderer;
		skeletonTransformIsParent = object.ReferenceEquals(skeletonTransform, base.transform.parent);
		bone = null;
		point = null;
		if (!string.IsNullOrEmpty(pointAttachmentName))
		{
			Skeleton skeleton = skeletonRenderer.skeleton;
			int num = skeleton.FindSlotIndex(slotName);
			if (num >= 0)
			{
				Slot slot = skeleton.slots.Items[num];
				bone = slot.bone;
				point = (skeleton.GetAttachment(num, pointAttachmentName) as PointAttachment);
			}
		}
	}

	public void LateUpdate()
	{
		if (point == null)
		{
			if (string.IsNullOrEmpty(pointAttachmentName))
			{
				return;
			}
			UpdateReferences();
			if (point == null)
			{
				return;
			}
		}
		Vector2 vector = default(Vector2);
		point.ComputeWorldPosition(bone, out vector.x, out vector.y);
		float num = point.ComputeWorldRotation(bone);
		Transform transform = base.transform;
		Quaternion quaternion;
		if (skeletonTransformIsParent)
		{
			Transform transform2 = transform;
			float x = vector.x;
			float y = vector.y;
			float z;
			if (followSkeletonZPosition)
			{
				z = 0f;
			}
			else
			{
				Vector3 localPosition = transform.localPosition;
				z = localPosition.z;
			}
			transform2.localPosition = new Vector3(x, y, z);
			if (followRotation)
			{
				float f = num * 0.5f * 0.0174532924f;
				quaternion = default(Quaternion);
				Quaternion localRotation = quaternion;
				localRotation.z = Mathf.Sin(f);
				localRotation.w = Mathf.Cos(f);
				transform.localRotation = localRotation;
			}
		}
		else
		{
			Vector3 position = skeletonTransform.TransformPoint(new Vector3(vector.x, vector.y, 0f));
			if (!followSkeletonZPosition)
			{
				Vector3 position2 = transform.position;
				position.z = position2.z;
			}
			Transform parent = transform.parent;
			if ((Object)parent != (Object)null)
			{
				Matrix4x4 localToWorldMatrix = parent.localToWorldMatrix;
				if (localToWorldMatrix.m00 * localToWorldMatrix.m11 - localToWorldMatrix.m01 * localToWorldMatrix.m10 < 0f)
				{
					num = 0f - num;
				}
			}
			if (followRotation)
			{
				quaternion = skeletonTransform.rotation;
				Vector3 eulerAngles = quaternion.eulerAngles;
				transform.SetPositionAndRotation(position, Quaternion.Euler(eulerAngles.x, eulerAngles.y, eulerAngles.z + num));
			}
			else
			{
				transform.position = position;
			}
		}
		if (followSkeletonFlip)
		{
			Vector3 localScale = transform.localScale;
			localScale.y = Mathf.Abs(localScale.y) * ((!(bone.skeleton.flipX ^ bone.skeleton.flipY)) ? 1f : (-1f));
			transform.localScale = localScale;
		}
	}
}

   

ISQR是一种基于网络科学和社会学的谣言播模型,以下是一个简单的Python代码实现: ```python import networkx as nx import random # 初始化网络 def initialize_network(n, m): G = nx.barabasi_albert_graph(n, m) for node in G.nodes(): G.nodes[node]['state'] = 0 # 0表示未被激活,1表示已被激活 return G # 初始化种子节点 def initialize_seeds(G, k): seeds = random.sample(G.nodes(), k) for seed in seeds: G.nodes[seed]['state'] = 1 return seeds # 计算节点的播概率 def calculate_propagation_probability(G, p): for node in G.nodes(): G.nodes[node]['propagation_probability'] = 1 - (1 - p) ** G.degree(node) # 模拟谣言播过程 def simulate_spread_of_rumor(G, seeds): active_nodes = seeds.copy() while active_nodes: node = active_nodes.pop(0) for neighbor in G.neighbors(node): # 如果邻居节点未被激活,则以一定概率激活该节点 if G.nodes[neighbor]['state'] == 0: propagation_probability = G.nodes[neighbor]['propagation_probability'] if random.uniform(0, 1) < propagation_probability: G.nodes[neighbor]['state'] = 1 active_nodes.append(neighbor) # 计算谣言播的影响范围 def calculate_influence_range(G): influence_range = 0 for node in G.nodes(): if G.nodes[node]['state'] == 1: influence_range += 1 return influence_range # 运行ISQR模型 def run_ISQR_model(n, m, k, p, iterations): influence_range_list = [] for i in range(iterations): G = initialize_network(n, m) seeds = initialize_seeds(G, k) calculate_propagation_probability(G, p) simulate_spread_of_rumor(G, seeds) influence_range = calculate_influence_range(G) influence_range_list.append(influence_range) return influence_range_list ``` 其中,`initialize_network`函数用于初始化网络,`initialize_seeds`函数用于初始化种子节点,`calculate_propagation_probability`函数用于计算节点的播概率,`simulate_spread_of_rumor`函数用于模拟谣言播过程,`calculate_influence_range`函数用于计算谣言播的影响范围,`run_ISQR_model`函数用于运行ISQR模型并返回多次运行的结果。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值